Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/riastradh-drm2]: src/sys Add partial Linux i2c shim.



details:   https://anonhg.NetBSD.org/src/rev/ca0b62e718a3
branches:  riastradh-drm2
changeset: 788311:ca0b62e718a3
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Wed Jul 24 03:11:44 2013 +0000

description:
Add partial Linux i2c shim.

Just the parts we need for i915drm for now -- well, most of them;
more to come later.

diffstat:

 sys/external/bsd/drm2/include/linux/i2c-algo-bit.h |   24 +-
 sys/external/bsd/drm2/include/linux/i2c.h          |   59 ++++-
 sys/external/bsd/drm2/linux/linux_i2c.c            |  251 +++++++++++++++++++++
 sys/modules/drm2/Makefile                          |    6 +-
 4 files changed, 336 insertions(+), 4 deletions(-)

diffs (truncated from 386 to 300 lines):

diff -r 846d20157d22 -r ca0b62e718a3 sys/external/bsd/drm2/include/linux/i2c-algo-bit.h
--- a/sys/external/bsd/drm2/include/linux/i2c-algo-bit.h        Wed Jul 24 03:11:21 2013 +0000
+++ b/sys/external/bsd/drm2/include/linux/i2c-algo-bit.h        Wed Jul 24 03:11:44 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: i2c-algo-bit.h,v 1.1.2.1 2013/07/24 00:33:12 riastradh Exp $   */
+/*     $NetBSD: i2c-algo-bit.h,v 1.1.2.2 2013/07/24 03:11:44 riastradh Exp $   */
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -32,4 +32,26 @@
 #ifndef _LINUX_I2C_ALGO_BIT_H_
 #define _LINUX_I2C_ALGO_BIT_H_
 
+struct i2c_adapter;
+
+struct i2c_algo_bit_data {
+       void            *data;
+       void            (*setsda)(void *, int);
+       void            (*setscl)(void *, int);
+       int             (*getsda)(void *);
+       int             (*getscl)(void *);
+       int             (*pre_xfer)(struct i2c_adapter *);
+       void            (*post_xfer)(struct i2c_adapter *);
+       int             udelay;
+       int             timeout;
+};
+
+/* XXX Make the nm output a little more greppable...  */
+#define        i2c_bit_add_bus linux_i2c_bit_add_bus
+#define        i2c_bit_algo    linux_i2c_bit_algo
+
+int    i2c_bit_add_bus(struct i2c_adapter *);
+
+extern const struct i2c_algorithm i2c_bit_algo;
+
 #endif  /* _LINUX_I2C_ALGO_BIT_H_ */
diff -r 846d20157d22 -r ca0b62e718a3 sys/external/bsd/drm2/include/linux/i2c.h
--- a/sys/external/bsd/drm2/include/linux/i2c.h Wed Jul 24 03:11:21 2013 +0000
+++ b/sys/external/bsd/drm2/include/linux/i2c.h Wed Jul 24 03:11:44 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: i2c.h,v 1.1.2.3 2013/07/24 02:35:49 riastradh Exp $    */
+/*     $NetBSD: i2c.h,v 1.1.2.4 2013/07/24 03:11:44 riastradh Exp $    */
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -34,9 +34,64 @@
 
 #include <sys/types.h>
 #include <sys/device_if.h>
+#include <sys/queue.h>         /* XXX include order botch: i2cvar.h needs */
+
+#include <dev/i2c/i2cvar.h>
+
+struct i2c_adapter;
+struct i2c_algorithm;
+struct i2c_msg;
+
+#define        I2C_NAME_SIZE   20
+
+#define        I2C_CLASS_DDC   0x01
 
 struct i2c_adapter {
-       device_t ia_dev;
+       char                            name[I2C_NAME_SIZE];
+       const struct i2c_algorithm      *algo;
+       void                            *algo_data;
+       int                             retries;
+       struct module                   *owner;
+       unsigned int                    class;
 };
 
+static inline int
+i2c_add_adapter(struct i2c_adapter *adapter __unused)
+{
+       return 0;
+}
+
+static inline void
+i2c_del_adapter(struct i2c_adapter *adapter __unused)
+{
+}
+
+struct i2c_msg {
+       i2c_addr_t      addr;
+       uint16_t        flags;
+       uint16_t        len;
+       uint8_t         *buf;
+};
+
+#define        I2C_M_RD                0x01
+#define        I2C_M_NOSTART           0x02
+
+#define        I2C_FUNC_I2C                    0x01
+#define        I2C_FUNC_NOSTART                0x02
+#define        I2C_FUNC_SMBUS_EMUL             0x04
+#define        I2C_FUNC_SMBUS_READ_BLOCK_DATA  0x08
+#define        I2C_FUNC_SMBUS_BLOCK_PROC_CALL  0x10
+#define        I2C_FUNC_10BIT_ADDR             0x20
+
+struct i2c_algorithm {
+       int             (*master_xfer)(struct i2c_adapter *, struct i2c_msg *,
+                           int);
+       uint32_t        (*functionality)(struct i2c_adapter *);
+};
+
+/* XXX Make the nm output a little more greppable...  */
+#define        i2c_transfer    linux_i2c_transfer
+
+int    i2c_transfer(struct i2c_adapter *, struct i2c_msg *, int);
+
 #endif  /* _LINUX_I2C_H_ */
diff -r 846d20157d22 -r ca0b62e718a3 sys/external/bsd/drm2/linux/linux_i2c.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/external/bsd/drm2/linux/linux_i2c.c   Wed Jul 24 03:11:44 2013 +0000
@@ -0,0 +1,251 @@
+/*     $NetBSD: linux_i2c.c,v 1.1.2.1 2013/07/24 03:11:44 riastradh Exp $      */
+
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Taylor R. Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: linux_i2c.c,v 1.1.2.1 2013/07/24 03:11:44 riastradh Exp $");
+
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <sys/queue.h>         /* XXX include order botch: i2cvar.h needs */
+
+#include <dev/i2c/i2cvar.h>
+#include <dev/i2c/i2c_bitbang.h> /* XXX include order botch */
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+
+static int     netbsd_i2c_transfer(i2c_tag_t, struct i2c_msg *, int);
+static i2c_op_t        linux_i2c_flags_op(uint16_t, bool);
+static int     linux_i2c_flags_flags(uint16_t);
+static uint32_t        linux_i2cbb_functionality(struct i2c_adapter *);
+static int     linux_i2cbb_xfer(struct i2c_adapter *, struct i2c_msg *, int);
+static void    linux_i2cbb_set_bits(void *, uint32_t);
+static uint32_t        linux_i2cbb_read_bits(void *);
+static void    linux_i2cbb_set_dir(void *, uint32_t);
+static int     linux_i2cbb_send_start(void *, int);
+static int     linux_i2cbb_send_stop(void *, int);
+static int     linux_i2cbb_initiate_xfer(void *, i2c_addr_t, int);
+static int     linux_i2cbb_read_byte(void *, uint8_t *, int);
+static int     linux_i2cbb_write_byte(void *, uint8_t, int);
+
+int
+i2c_transfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int n)
+{
+
+       return (*adapter->algo->master_xfer)(adapter, msgs, n);
+}
+
+static int
+netbsd_i2c_transfer(i2c_tag_t i2c, struct i2c_msg *msgs, int n)
+{
+       int i;
+       int error;
+
+       for (i = 0; i < n; i++) {
+               const i2c_op_t op = linux_i2c_flags_op(msgs[i].flags,
+                   ((i + 1) == n));
+               const int flags = linux_i2c_flags_flags(msgs[i].flags);
+
+               switch (op) {
+               case I2C_OP_READ:
+               case I2C_OP_READ_WITH_STOP:
+                       error = iic_exec(i2c, op, msgs[i].addr,
+                           NULL, 0, msgs[i].buf, msgs[i].len, flags);
+                       break;
+
+               case I2C_OP_WRITE:
+               case I2C_OP_WRITE_WITH_STOP:
+                       error = iic_exec(i2c, op, msgs[i].addr,
+                           msgs[i].buf, msgs[i].len, NULL, 0, flags);
+                       break;
+
+               default:
+                       error = EINVAL;
+               }
+
+               if (error)
+                       /* XXX errno NetBSD->Linux */
+                       return -error;
+       }
+
+       return n;
+}
+
+static i2c_op_t
+linux_i2c_flags_op(uint16_t flags, bool stop)
+{
+
+       if (ISSET(flags, I2C_M_RD))
+               return (stop? I2C_OP_READ_WITH_STOP : I2C_OP_READ);
+       else
+               return (stop? I2C_OP_WRITE_WITH_STOP : I2C_OP_WRITE);
+}
+
+static int
+linux_i2c_flags_flags(uint16_t flags __unused)
+{
+
+       return 0;
+}
+
+const struct i2c_algorithm i2c_bit_algo = {
+       .master_xfer    = linux_i2cbb_xfer,
+       .functionality  = linux_i2cbb_functionality,
+};
+
+static uint32_t
+linux_i2cbb_functionality(struct i2c_adapter *adapter __unused)
+{
+       uint32_t functions = 0;
+
+       functions |= I2C_FUNC_I2C;
+       functions |= I2C_FUNC_NOSTART;
+       functions |= I2C_FUNC_SMBUS_EMUL;
+       functions |= I2C_FUNC_SMBUS_READ_BLOCK_DATA;
+       functions |= I2C_FUNC_SMBUS_BLOCK_PROC_CALL;
+#if 0
+       functions |= I2C_FUNC_10BIT_ADDR;
+       functions |= I2C_FUNC_PROTOCOL_MANGLING;
+#endif
+
+       return functions;
+}
+
+static int
+linux_i2cbb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int n)
+{
+       struct i2c_algo_bit_data *const abd = adapter->algo_data;
+       struct i2c_controller controller = {
+               .ic_cookie              = abd,
+               .ic_send_start          = linux_i2cbb_send_start,
+               .ic_send_stop           = linux_i2cbb_send_stop,
+               .ic_initiate_xfer       = linux_i2cbb_initiate_xfer,
+               .ic_read_byte           = linux_i2cbb_read_byte,
+               .ic_write_byte          = linux_i2cbb_write_byte,
+       };
+       i2c_tag_t i2c = &controller;
+       int error;
+
+       if (abd->pre_xfer) {
+               error = (*abd->pre_xfer)(adapter);
+               if (error)
+                       return error;
+       }
+
+       error = netbsd_i2c_transfer(i2c, msgs, n);
+
+       if (abd->post_xfer)
+               (*abd->post_xfer)(adapter);
+
+       return error;
+}
+
+#define        LI2CBB_SDA      0x01
+#define        LI2CBB_SCL      0x02
+#define        LI2CBB_INPUT    0x04
+#define        LI2CBB_OUTPUT   0x08
+
+static struct i2c_bitbang_ops linux_i2cbb_ops = {
+       .ibo_set_bits   = linux_i2cbb_set_bits,
+       .ibo_set_dir    = linux_i2cbb_set_dir,
+       .ibo_read_bits  = linux_i2cbb_read_bits,
+       .ibo_bits       = {
+               [I2C_BIT_SDA]           = LI2CBB_SDA,
+               [I2C_BIT_SCL]           = LI2CBB_SCL,
+               [I2C_BIT_INPUT]         = LI2CBB_INPUT,
+               [I2C_BIT_OUTPUT]        = LI2CBB_OUTPUT,
+       },



Home | Main Index | Thread Index | Old Index