[PATCH RFC] eeprom: at24: extend driver to plug into the NVMEM framework

2015-08-15 Thread Andrew Lunn
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

2015-08-15 Thread Joachim Eastwood
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

2015-08-15 Thread Jonathan Cameron
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

2015-08-15 Thread Wolfram Sang
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

2015-08-15 Thread Wolfram Sang
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