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