[PATCH RFC] eeprom: at24: extend driver to plug into the NVMEM framework
Add a read only regmap for accessing the EEPROM, and then use that with the NVMEM framework. Signed-off-by: Andrew Lunn and...@lunn.ch --- drivers/misc/eeprom/at24.c | 65 ++ 1 file changed, 65 insertions(+) diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index 2d3db81be099..0e80c0c09d4e 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c @@ -22,6 +22,8 @@ #include linux/jiffies.h #include linux/of.h #include linux/i2c.h +#include linux/nvmem-provider.h +#include linux/regmap.h #include linux/platform_data/at24.h /* @@ -69,6 +71,10 @@ struct at24_data { unsigned write_max; unsigned num_addresses; + struct regmap_config regmap_config; + struct nvmem_config nvmem_config; + struct nvmem_device *nvmem; + /* * Some chips tie up multiple I2C addresses; dummy devices reserve * them for us, and we'll use them with SMBus calls. @@ -471,6 +477,34 @@ static ssize_t at24_macc_write(struct memory_accessor *macc, const char *buf, /*-*/ +/* + * Provide a regmap interface, which is registered with the NVMEM + * framework +*/ +static int at24_regmap_read(void *context, const void *reg, size_t reg_size, + void *val, size_t val_size) +{ + struct at24_data *at24 = context; + off_t offset = *(u32 *)reg; + + return at24_read(at24, val, offset, val_size); +} + +static int at24_regmap_write(void *context, const void *data, size_t count) +{ + struct at24_data *at24 = context; + + return at24_write(at24, data, 0, count); +} + +static const struct regmap_bus at24_regmap_bus = { + .read = at24_regmap_read, + .write = at24_regmap_write, + .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, +}; + +/*-*/ + #ifdef CONFIG_OF static void at24_get_ofdata(struct i2c_client *client, struct at24_platform_data *chip) @@ -502,6 +536,7 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) int err; unsigned i, num_addresses; kernel_ulong_t magic; + struct regmap *regmap; if (client-dev.platform_data) { chip = *(struct at24_platform_data *)client-dev.platform_data; @@ -644,6 +679,30 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) if (err) goto err_clients; + at24-regmap_config.reg_bits = 32; + at24-regmap_config.val_bits = 8; + at24-regmap_config.reg_stride = 1; + at24-regmap_config.max_register = at24-bin.size - 1; + + regmap = devm_regmap_init(client-dev, at24_regmap_bus, at24, + at24-regmap_config); + if (IS_ERR(regmap)) { + dev_err(client-dev, regmap init failed\n); + err = PTR_ERR(regmap); + goto err_sysfs; + } + + at24-nvmem_config.name = dev_name(client-dev); + at24-nvmem_config.dev = client-dev; + at24-nvmem_config.read_only = !writable; + at24-nvmem_config.owner = THIS_MODULE; + + at24-nvmem = nvmem_register(at24-nvmem_config); + if (IS_ERR(at24-nvmem)) { + err = PTR_ERR(at24-nvmem); + goto err_sysfs; + } + i2c_set_clientdata(client, at24); dev_info(client-dev, %zu byte %s EEPROM, %s, %u bytes/write\n, @@ -662,6 +721,9 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) return 0; +err_sysfs: + sysfs_remove_bin_file(client-dev.kobj, at24-bin); + err_clients: for (i = 1; i num_addresses; i++) if (at24-client[i]) @@ -676,6 +738,9 @@ static int at24_remove(struct i2c_client *client) int i; at24 = i2c_get_clientdata(client); + + nvmem_unregister(at24-nvmem); + sysfs_remove_bin_file(client-dev.kobj, at24-bin); for (i = 1; i at24-num_addresses; i++) -- 2.5.0 -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] i2c: add i2c-lpc2k driver
Hi Wolfram, On 15 August 2015 at 22:24, Wolfram Sang w...@the-dreams.de wrote: On Mon, Jul 13, 2015 at 12:47:21AM +0200, Joachim Eastwood wrote: Add support for the I2C controller found on several NXP devices including LPC2xxx, LPC178x/7x and LPC18xx/43xx. The controller is implemented as a state machine and the driver act upon the state changes when the bus is accessed. The I2C controller supports master/slave operation, bus arbitration, programmable clock rate, and speeds up to 1 Mbit/s. Signed-off-by: Joachim Eastwood manab...@gmail.com Thanks for the submission! Looking mostly good already. +static void i2c_lpc2k_pump_msg(struct lpc2k_i2c *i2c) +{ + unsigned char data; + u32 status; + + /* + * I2C in the LPC2xxx series is basically a state machine. + * Just run through the steps based on the current status. + */ + status = readl(i2c-reg_base + LPC24XX_I2STAT); + + switch (status) { + case M_START: + case M_REPSTART: + /* Start bit was just sent out, send out addr and dir */ + data = (i2c-msg-addr 1); + if (i2c-msg-flags I2C_M_RD) + data |= 1; + + writel(data, i2c-reg_base + LPC24XX_I2DAT); + writel(LPC24XX_STA, i2c-reg_base + LPC24XX_I2CONCLR); + + dev_dbg(i2c-adap.dev, Start sent with addr 0x%02x\n, data); I assume the driver is basically working. So, in my book, most of this debug output is useful when the driver was developed, not so much afterwards. Also, it is printed in interrupt context possibly causing latency. However, the information is useful for understanding the driver, so I'd suggest to convert them into comments? I'll go through all the dev_dbg stuff with what you wrote in mind. Think I'll end up with removing most of it. Think most of the debugging stuff was added by Emcraft while they were bring it up on lpc178x and lpc18xx. + i2c-adap.nr = pdev-id; + + ret = i2c_add_numbered_adapter(i2c-adap); Intended? Most DT enabled drivers simply user i2c_add_adapter(). The core then takes care of aliases defined in DT. No, it's not intended. It's an old driver and I just didn't know about i2c_add_adapter(). I'll change it in the next version. And please have a look at Documentation/i2c/fault-codes. Arbitration Lost should be -EAGAIN, NACK should be -ENXIO, and so forth... Ok, will do. Thanks for looking, Wolfram. I'll address your comments and try to send out a new version tomorrow. regards, Joachim Eastwood -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 2/8] eeprom: at24: use i2c_smbus_read_i2c_block_data_or_emulated
On 14/08/15 19:24, Wolfram Sang wrote: On Wed, Aug 12, 2015 at 05:31:34PM +0300, Irina Tirdea wrote: For i2c busses that support only SMBUS extensions, the eeprom at24 driver reads data from the device using the SMBus block, word or byte read protocols depending on availability. Replace the block read emulation from the driver with the i2c_smbus_read_i2c_block_data_or_emulated call from i2c core. Signed-off-by: Irina Tirdea irina.tir...@intel.com Applied to for-next, thanks! Cool. These will presumably make it in during the coming merge window. I'll pick up the IIO ones next cycle (IIO merge is probably now closed anyway as Linus is talking about merge window opening next week I think). Good work Irina, Jonathan -- To unsubscribe from this list: send the line unsubscribe linux-iio in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] driver/i2c/mux: Add register based mux i2c-mux-reg
On Tue, Jun 16, 2015 at 10:28:12AM -0700, York Sun wrote: Based on i2c-mux-gpio driver, similarly the register based mux switch from one bus to another by setting a single register. The register can be on PCIe bus, local bus, or any memory-mapped address. Signed-off-by: York Sun york...@freescale.com CC: Wolfram Sang w...@the-dreams.de CC: Peter Korsgaard peter.korsga...@barco.com Mostly good. +static int i2c_mux_reg_probe(struct platform_device *pdev) +{ + struct regmux *mux; + struct i2c_adapter *parent; + struct resource *res; + int (*deselect)(struct i2c_adapter *, void *, u32); + unsigned int initial_state, class; gcc says: drivers/i2c/muxes/i2c-mux-reg.c:182:15: warning: variable 'initial_state' set but not used [-Wunused-but-set-variable] It seens you prepared for setting the initial state but don't do the actual set? +static struct platform_driver i2c_mux_reg_driver = { + .probe = i2c_mux_reg_probe, + .remove = i2c_mux_reg_remove, + .driver = { + .owner = THIS_MODULE, coccicheck says: drivers/i2c/muxes/i2c-mux-reg.c:288:3-8: No need to set .owner here. The core will do it. + .name = i2c-mux-reg, + }, +}; Thanks, Wolfram -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] i2c: add i2c-lpc2k driver
On Mon, Jul 13, 2015 at 12:47:21AM +0200, Joachim Eastwood wrote: Add support for the I2C controller found on several NXP devices including LPC2xxx, LPC178x/7x and LPC18xx/43xx. The controller is implemented as a state machine and the driver act upon the state changes when the bus is accessed. The I2C controller supports master/slave operation, bus arbitration, programmable clock rate, and speeds up to 1 Mbit/s. Signed-off-by: Joachim Eastwood manab...@gmail.com Thanks for the submission! Looking mostly good already. +static void i2c_lpc2k_pump_msg(struct lpc2k_i2c *i2c) +{ + unsigned char data; + u32 status; + + /* + * I2C in the LPC2xxx series is basically a state machine. + * Just run through the steps based on the current status. + */ + status = readl(i2c-reg_base + LPC24XX_I2STAT); + + switch (status) { + case M_START: + case M_REPSTART: + /* Start bit was just sent out, send out addr and dir */ + data = (i2c-msg-addr 1); + if (i2c-msg-flags I2C_M_RD) + data |= 1; + + writel(data, i2c-reg_base + LPC24XX_I2DAT); + writel(LPC24XX_STA, i2c-reg_base + LPC24XX_I2CONCLR); + + dev_dbg(i2c-adap.dev, Start sent with addr 0x%02x\n, data); I assume the driver is basically working. So, in my book, most of this debug output is useful when the driver was developed, not so much afterwards. Also, it is printed in interrupt context possibly causing latency. However, the information is useful for understanding the driver, so I'd suggest to convert them into comments? + i2c-adap.nr = pdev-id; + + ret = i2c_add_numbered_adapter(i2c-adap); Intended? Most DT enabled drivers simply user i2c_add_adapter(). The core then takes care of aliases defined in DT. And please have a look at Documentation/i2c/fault-codes. Arbitration Lost should be -EAGAIN, NACK should be -ENXIO, and so forth... Thanks, Wolfram -- To unsubscribe from this list: send the line unsubscribe linux-i2c in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html