From b550ad407122e5548062810964924aa830366c9b Mon Sep 17 00:00:00 2001 From: Alessandro Rubini <rubini@gnudd.com> Date: Tue, 24 Jul 2012 15:32:20 +0200 Subject: [PATCH] spec-i2c: massive change to use fmc_readl/writel --- kernel/spec-i2c.c | 142 ++++++++++++++++++++++------------------------ 1 file changed, 67 insertions(+), 75 deletions(-) diff --git a/kernel/spec-i2c.c b/kernel/spec-i2c.c index e5624e4..4fba4af 100644 --- a/kernel/spec-i2c.c +++ b/kernel/spec-i2c.c @@ -15,9 +15,11 @@ #include <linux/time.h> #include <linux/pci.h> #include <linux/slab.h> +#include <linux/fmc.h> #include "spec.h" #include "hw/fd_main_regs.h" + static int spec_i2c_dump; module_param_named(i2c_dump, spec_i2c_dump, int, 0444); @@ -25,16 +27,6 @@ module_param_named(i2c_dump, spec_i2c_dump, int, 0444); #define I2C_ADDR 0x50 #define I2C_SIZE (8 * 1024) -/* FIXME: this is a temporary hack: we should use the operations instead */ -static inline uint32_t spec_readl(struct spec_dev *spec, int off) -{ - return readl(spec->remap[0] + 0x80000 + off); -} -static inline void spec_writel(struct spec_dev *spec, uint32_t val, int off) -{ - writel(val, spec->remap[0] + 0x80000 + off); -} - /* Stupid dumping tool */ static void dumpstruct(char *name, void *ptr, int size) { @@ -51,111 +43,111 @@ static void dumpstruct(char *name, void *ptr, int size) printk("\n"); } -static void set_sda(struct spec_dev *spec, int val) +static void set_sda(struct fmc_device *fmc, int val) { uint32_t reg; - reg = spec_readl(spec, FD_REG_I2CR) & ~FD_I2CR_SDA_OUT; + reg = fmc_readl(fmc, FD_REG_I2CR) & ~FD_I2CR_SDA_OUT; if (val) reg |= FD_I2CR_SDA_OUT; - spec_writel(spec, reg, FD_REG_I2CR); + fmc_writel(fmc, reg, FD_REG_I2CR); } -static void set_scl(struct spec_dev *spec, int val) +static void set_scl(struct fmc_device *fmc, int val) { uint32_t reg; - reg = spec_readl(spec, FD_REG_I2CR) & ~FD_I2CR_SCL_OUT; + reg = fmc_readl(fmc, FD_REG_I2CR) & ~FD_I2CR_SCL_OUT; if (val) reg |= FD_I2CR_SCL_OUT; - spec_writel(spec, reg, FD_REG_I2CR); + fmc_writel(fmc, reg, FD_REG_I2CR); } -static int get_sda(struct spec_dev *spec) +static int get_sda(struct fmc_device *fmc) { - return spec_readl(spec, FD_REG_I2CR) & FD_I2CR_SDA_IN ? 1 : 0; + return fmc_readl(fmc, FD_REG_I2CR) & FD_I2CR_SDA_IN ? 1 : 0; }; -static void mi2c_start(struct spec_dev *spec) +static void mi2c_start(struct fmc_device *fmc) { - set_sda(spec, 0); - set_scl(spec, 0); + set_sda(fmc, 0); + set_scl(fmc, 0); } -static void mi2c_stop(struct spec_dev *spec) +static void mi2c_stop(struct fmc_device *fmc) { - set_sda(spec, 0); - set_scl(spec, 1); - set_sda(spec, 1); + set_sda(fmc, 0); + set_scl(fmc, 1); + set_sda(fmc, 1); } -int mi2c_put_byte(struct spec_dev *spec, int data) +int mi2c_put_byte(struct fmc_device *fmc, int data) { int i; int ack; for (i = 0; i < 8; i++, data<<=1) { - set_sda(spec, data & 0x80); - set_scl(spec, 1); - set_scl(spec, 0); + set_sda(fmc, data & 0x80); + set_scl(fmc, 1); + set_scl(fmc, 0); } - set_sda(spec, 1); - set_scl(spec, 1); + set_sda(fmc, 1); + set_scl(fmc, 1); - ack = get_sda(spec); + ack = get_sda(fmc); - set_scl(spec, 0); - set_sda(spec, 0); + set_scl(fmc, 0); + set_sda(fmc, 0); return ack ? -EIO : 0; /* ack low == success */ } -int mi2c_get_byte(struct spec_dev *spec, unsigned char *data, int sendack) +int mi2c_get_byte(struct fmc_device *fmc, unsigned char *data, int sendack) { int i; int indata = 0; /* assert: scl is low */ - set_scl(spec, 0); - set_sda(spec, 1); + set_scl(fmc, 0); + set_sda(fmc, 1); for (i = 0; i < 8; i++) { - set_scl(spec, 1); + set_scl(fmc, 1); indata <<= 1; - if (get_sda(spec)) + if (get_sda(fmc)) indata |= 0x01; - set_scl(spec, 0); + set_scl(fmc, 0); } - set_sda(spec, (sendack ? 0 : 1)); - set_scl(spec, 1); - set_scl(spec, 0); - set_sda(spec, 0); + set_sda(fmc, (sendack ? 0 : 1)); + set_scl(fmc, 1); + set_scl(fmc, 0); + set_sda(fmc, 0); *data= indata; return 0; } -void mi2c_init(struct spec_dev *spec) +void mi2c_init(struct fmc_device *fmc) { - set_scl(spec, 1); - set_sda(spec, 1); + set_scl(fmc, 1); + set_sda(fmc, 1); } -void mi2c_scan(struct spec_dev *spec) +void mi2c_scan(struct fmc_device *fmc) { int i; for(i = 0; i < 256; i += 2) { - mi2c_start(spec); - if(!mi2c_put_byte(spec, i)) + mi2c_start(fmc); + if(!mi2c_put_byte(fmc, i)) pr_info("%s: Found i2c device at 0x%x\n", KBUILD_MODNAME, i >> 1); - mi2c_stop(spec); + mi2c_stop(fmc); } } /* FIXME: this is very inefficient: read several bytes in a row instead */ -int spec_eeprom_read(struct spec_dev *spec, int i2c_addr, uint32_t offset, +int spec_eeprom_read(struct fmc_device *fmc, int i2c_addr, uint32_t offset, void *buf, size_t size) { int i; @@ -163,48 +155,48 @@ int spec_eeprom_read(struct spec_dev *spec, int i2c_addr, uint32_t offset, unsigned char c; for(i = 0; i < size; i++) { - mi2c_start(spec); - if(mi2c_put_byte(spec, i2c_addr << 1) < 0) { - mi2c_stop(spec); + mi2c_start(fmc); + if(mi2c_put_byte(fmc, i2c_addr << 1) < 0) { + mi2c_stop(fmc); return -EIO; } - mi2c_put_byte(spec, (offset >> 8) & 0xff); - mi2c_put_byte(spec, offset & 0xff); + mi2c_put_byte(fmc, (offset >> 8) & 0xff); + mi2c_put_byte(fmc, offset & 0xff); offset++; - mi2c_stop(spec); - mi2c_start(spec); - mi2c_put_byte(spec, (i2c_addr << 1) | 1); - mi2c_get_byte(spec, &c, 0); + mi2c_stop(fmc); + mi2c_start(fmc); + mi2c_put_byte(fmc, (i2c_addr << 1) | 1); + mi2c_get_byte(fmc, &c, 0); *buf8++ = c; - mi2c_stop(spec); + mi2c_stop(fmc); } return size; } -int spec_eeprom_write(struct spec_dev *spec, int i2c_addr, uint32_t offset, +int spec_eeprom_write(struct fmc_device *fmc, int i2c_addr, uint32_t offset, void *buf, size_t size) { int i, busy; uint8_t *buf8 = buf; for(i = 0; i < size; i++) { - mi2c_start(spec); + mi2c_start((fmc)); - if(mi2c_put_byte(spec, i2c_addr << 1) < 0) { - mi2c_stop(spec); + if(mi2c_put_byte(fmc, i2c_addr << 1) < 0) { + mi2c_stop(fmc); return -1; } - mi2c_put_byte(spec, (offset >> 8) & 0xff); - mi2c_put_byte(spec, offset & 0xff); - mi2c_put_byte(spec, *buf8++); + mi2c_put_byte(fmc, (offset >> 8) & 0xff); + mi2c_put_byte(fmc, offset & 0xff); + mi2c_put_byte(fmc, *buf8++); offset++; - mi2c_stop(spec); + mi2c_stop(fmc); do { /* wait until the chip becomes ready */ - mi2c_start(spec); - busy = mi2c_put_byte(spec, i2c_addr << 1); - mi2c_stop(spec); + mi2c_start(fmc); + busy = mi2c_put_byte(fmc, i2c_addr << 1); + mi2c_stop(fmc); } while(busy); } return size; @@ -216,13 +208,13 @@ int spec_i2c_init(struct fmc_device *fmc) void *buf; int i; - mi2c_scan(spec); + mi2c_scan(fmc); buf = kmalloc(I2C_SIZE, GFP_KERNEL); if (!buf) return -ENOMEM; - i = spec_eeprom_read(spec, I2C_ADDR, 0, buf, I2C_SIZE); + i = spec_eeprom_read(fmc, I2C_ADDR, 0, buf, I2C_SIZE); if (i != I2C_SIZE) { dev_err(&spec->pdev->dev, "EEPROM read error: retval is %i\n", i); -- GitLab