Module Name: src Committed By: riastradh Date: Thu Mar 5 17:29:18 UTC 2015
Modified Files: src/sys/external/bsd/drm2/include/linux: i2c.h src/sys/external/bsd/drm2/linux: linux_i2c.c Log Message: Reorganize Linux i2c header file and add a few more shims. To generate a diff of this commit: cvs rdiff -u -r1.7 -r1.8 src/sys/external/bsd/drm2/include/linux/i2c.h cvs rdiff -u -r1.2 -r1.3 src/sys/external/bsd/drm2/linux/linux_i2c.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/external/bsd/drm2/include/linux/i2c.h diff -u src/sys/external/bsd/drm2/include/linux/i2c.h:1.7 src/sys/external/bsd/drm2/include/linux/i2c.h:1.8 --- src/sys/external/bsd/drm2/include/linux/i2c.h:1.7 Thu Mar 5 15:02:36 2015 +++ src/sys/external/bsd/drm2/include/linux/i2c.h Thu Mar 5 17:29:18 2015 @@ -1,7 +1,7 @@ -/* $NetBSD: i2c.h,v 1.7 2015/03/05 15:02:36 riastradh Exp $ */ +/* $NetBSD: i2c.h,v 1.8 2015/03/05 17:29:18 riastradh Exp $ */ /*- - * Copyright (c) 2013 The NetBSD Foundation, Inc. + * Copyright (c) 2015 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -35,20 +35,86 @@ #include <sys/types.h> #include <sys/device_if.h> #include <sys/queue.h> /* XXX include order botch: i2cvar.h needs */ +#include <sys/systm.h> #include <dev/i2c/i2cvar.h> +#include <linux/pm.h> + struct i2c_adapter; struct i2c_algorithm; struct i2c_msg; #define I2C_NAME_SIZE 20 +/* + * I2C_M_*: i2c_msg flags + */ +#define I2C_M_RD 0x01 /* xfer is read, not write */ +#define I2C_M_NOSTART 0x02 /* don't initiate xfer */ +#define I2C_M_TEN 0x04 /* 10-bit chip address */ + +/* + * I2C_CLASS_*: i2c_adapter classes + */ #define I2C_CLASS_DDC 0x01 +/* + * I2C_FUNC_*: i2c_adapter functionality bits + */ +#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_msg: A single i2c message request on a particular + * address. Read if I2C_M_RD is set, write otherwise. + */ +struct i2c_msg { + i2c_addr_t addr; + uint16_t flags; /* I2C_M_* */ + uint16_t len; + uint8_t *buf; +}; + +/* + * struct i2c_adapter: An i2c bus controller. + */ +struct i2c_adapter { + char name[I2C_NAME_SIZE]; + const struct i2c_algorithm *algo; + void *algo_data; + int retries; + struct module *owner; + unsigned int class; /* I2C_CLASS_* */ + struct { + device_t parent; + } dev; + void *i2ca_adapdata; +}; + +/* + * struct i2c_algorithm: A procedure for transferring an i2c message on + * an i2c bus, along with a set of flags describing its functionality. + */ +struct i2c_algorithm { + int (*master_xfer)(struct i2c_adapter *, struct i2c_msg *, + int); + uint32_t (*functionality)(struct i2c_adapter *); +}; + +/* + * struct i2c_board_info: Parameters to find an i2c bus and a slave on + * it. type is the name of an i2c driver; addr is the slave address; + * platform_data is an extra parameter to pass to the i2c driver. + */ struct i2c_board_info { char type[I2C_NAME_SIZE]; uint16_t addr; + uint16_t flags; void *platform_data; }; @@ -56,46 +122,46 @@ struct i2c_board_info { .type = (board_type), \ .addr = (board_addr) -static inline void -i2c_new_device(const struct i2c_adapter *adapter __unused, - const struct i2c_board_info *board __unused) -{ -} - -struct i2c_driver { +/* + * struct i2c_client: An i2c slave device at a particular address on a + * particular bus. + */ +struct i2c_client { + struct i2c_adapter *adapter; + uint16_t addr; + uint16_t flags; }; -struct module; -static inline int -i2c_register_driver(const struct module *owner __unused, - const struct i2c_driver *driver __unused) -{ - return 0; -} - -static inline void -i2c_del_driver(const struct i2c_driver *driver __unused) -{ -} - -struct i2c_client; +/* + * struct i2c_device_id: Device id naming a class of i2c slave devices + * and parameters to the driver for the devices. + */ +struct i2c_device_id { + char name[I2C_NAME_SIZE]; + unsigned long driver_data; +}; -struct i2c_adapter { - char name[I2C_NAME_SIZE]; - const struct i2c_algorithm *algo; - void *algo_data; - int retries; - struct module *owner; - unsigned int class; +/* + * struct i2c_driver: A driver for a class of i2c slave devices. We + * don't actually use this. + */ +struct i2c_driver { + int (*probe)(struct i2c_client *, const struct i2c_device_id *); + int (*remove)(struct i2c_client *); struct { - device_t parent; - } dev; - void *i2ca_adapdata; + char name[I2C_NAME_SIZE]; + const struct dev_pm_ops pm; + } driver; }; +/* + * Adapter management. We don't register these in a global database + * like Linux, so these are just stubs. + */ static inline int i2c_add_adapter(struct i2c_adapter *adapter __unused) { + return 0; } @@ -118,32 +184,18 @@ i2c_set_adapdata(struct i2c_adapter *ada adapter->i2ca_adapdata = data; } -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 - +#define i2c_master_recv linux_i2c_master_recv +#define i2c_master_send linux_i2c_master_send +#define i2c_new_device linux_i2c_new_device +#define i2c_transfer linux_i2c_transfer +#define i2c_unregister_device linux_i2c_unregister_device + +int i2c_master_send(const struct i2c_client *, const char *, int); +int i2c_master_recv(const struct i2c_client *, char *, int); +struct i2c_client * + i2c_new_device(struct i2c_adapter *, const struct i2c_board_info *); int i2c_transfer(struct i2c_adapter *, struct i2c_msg *, int); +void i2c_unregister_device(struct i2c_client *); #endif /* _LINUX_I2C_H_ */ Index: src/sys/external/bsd/drm2/linux/linux_i2c.c diff -u src/sys/external/bsd/drm2/linux/linux_i2c.c:1.2 src/sys/external/bsd/drm2/linux/linux_i2c.c:1.3 --- src/sys/external/bsd/drm2/linux/linux_i2c.c:1.2 Tue Mar 18 18:20:43 2014 +++ src/sys/external/bsd/drm2/linux/linux_i2c.c Thu Mar 5 17:29:18 2015 @@ -1,7 +1,7 @@ -/* $NetBSD: linux_i2c.c,v 1.2 2014/03/18 18:20:43 riastradh Exp $ */ +/* $NetBSD: linux_i2c.c,v 1.3 2015/03/05 17:29:18 riastradh Exp $ */ /*- - * Copyright (c) 2013 The NetBSD Foundation, Inc. + * Copyright (c) 2015 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -30,10 +30,11 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: linux_i2c.c,v 1.2 2014/03/18 18:20:43 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: linux_i2c.c,v 1.3 2015/03/05 17:29:18 riastradh Exp $"); #include <sys/types.h> #include <sys/errno.h> +#include <sys/kmem.h> #include <sys/queue.h> /* XXX include order botch: i2cvar.h needs */ #include <dev/i2c/i2cvar.h> @@ -56,6 +57,73 @@ static int linux_i2cbb_initiate_xfer(voi static int linux_i2cbb_read_byte(void *, uint8_t *, int); static int linux_i2cbb_write_byte(void *, uint8_t, int); +/* + * Client operations: operations with a particular i2c slave device. + */ + +struct i2c_client * +i2c_new_device(struct i2c_adapter *adapter, const struct i2c_board_info *info) +{ + struct i2c_client *client; + + client = kmem_alloc(sizeof(*client), KM_SLEEP); + client->adapter = adapter; + client->addr = info->addr; + client->flags = info->flags; + + return client; +} + +void +i2c_unregister_device(struct i2c_client *client) +{ + + kmem_free(client, sizeof(*client)); +} + +int +i2c_master_send(const struct i2c_client *client, const char *buf, int count) +{ + struct i2c_msg msg = { + .addr = client->addr, + .flags = client->flags & I2C_M_TEN, + .len = count, + .buf = __UNCONST(buf), + }; + int ret; + + KASSERT(0 <= count); + + ret = i2c_transfer(client->adapter, &msg, 1); + if (ret <= 0) + return ret; + + return count; +} + +int +i2c_master_recv(const struct i2c_client *client, char *buf, int count) +{ + struct i2c_msg msg = { + .addr = client->addr, + .flags = (client->flags & I2C_M_TEN) | I2C_M_RD, + .len = count, + .buf = buf, + }; + int ret; + + ret = i2c_transfer(client->adapter, &msg, 1); + if (ret <= 0) + return ret; + + return count; +} + +/* + * Adapter operations: operations over an i2c bus via a particular + * controller. + */ + int i2c_transfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int n) { @@ -116,6 +184,8 @@ linux_i2c_flags_flags(uint16_t flags __u return 0; } +/* Bit-banging */ + const struct i2c_algorithm i2c_bit_algo = { .master_xfer = linux_i2cbb_xfer, .functionality = linux_i2cbb_functionality,