Loading drivers/i2c/busses/i2c-davinci.c +251 −63 Original line number Diff line number Diff line Loading @@ -36,14 +36,16 @@ #include <linux/platform_device.h> #include <linux/io.h> #include <linux/slab.h> #include <linux/cpufreq.h> #include <linux/gpio.h> #include <mach/hardware.h> #include <mach/i2c.h> /* ----- global defines ----------------------------------------------- */ #define DAVINCI_I2C_TIMEOUT (1*HZ) #define DAVINCI_I2C_MAX_TRIES 2 #define I2C_DAVINCI_INTR_ALL (DAVINCI_I2C_IMR_AAS | \ DAVINCI_I2C_IMR_SCD | \ DAVINCI_I2C_IMR_ARDY | \ Loading Loading @@ -72,37 +74,29 @@ #define DAVINCI_I2C_IVR_NACK 0x02 #define DAVINCI_I2C_IVR_AL 0x01 #define DAVINCI_I2C_STR_BB (1 << 12) #define DAVINCI_I2C_STR_RSFULL (1 << 11) #define DAVINCI_I2C_STR_SCD (1 << 5) #define DAVINCI_I2C_STR_ARDY (1 << 2) #define DAVINCI_I2C_STR_NACK (1 << 1) #define DAVINCI_I2C_STR_AL (1 << 0) #define DAVINCI_I2C_MDR_NACK (1 << 15) #define DAVINCI_I2C_MDR_STT (1 << 13) #define DAVINCI_I2C_MDR_STP (1 << 11) #define DAVINCI_I2C_MDR_MST (1 << 10) #define DAVINCI_I2C_MDR_TRX (1 << 9) #define DAVINCI_I2C_MDR_XA (1 << 8) #define DAVINCI_I2C_MDR_RM (1 << 7) #define DAVINCI_I2C_MDR_IRS (1 << 5) #define DAVINCI_I2C_IMR_AAS (1 << 6) #define DAVINCI_I2C_IMR_SCD (1 << 5) #define DAVINCI_I2C_IMR_XRDY (1 << 4) #define DAVINCI_I2C_IMR_RRDY (1 << 3) #define DAVINCI_I2C_IMR_ARDY (1 << 2) #define DAVINCI_I2C_IMR_NACK (1 << 1) #define DAVINCI_I2C_IMR_AL (1 << 0) #define MOD_REG_BIT(val, mask, set) do { \ if (set) { \ val |= mask; \ } else { \ val &= ~mask; \ } \ } while (0) #define DAVINCI_I2C_STR_BB BIT(12) #define DAVINCI_I2C_STR_RSFULL BIT(11) #define DAVINCI_I2C_STR_SCD BIT(5) #define DAVINCI_I2C_STR_ARDY BIT(2) #define DAVINCI_I2C_STR_NACK BIT(1) #define DAVINCI_I2C_STR_AL BIT(0) #define DAVINCI_I2C_MDR_NACK BIT(15) #define DAVINCI_I2C_MDR_STT BIT(13) #define DAVINCI_I2C_MDR_STP BIT(11) #define DAVINCI_I2C_MDR_MST BIT(10) #define DAVINCI_I2C_MDR_TRX BIT(9) #define DAVINCI_I2C_MDR_XA BIT(8) #define DAVINCI_I2C_MDR_RM BIT(7) #define DAVINCI_I2C_MDR_IRS BIT(5) #define DAVINCI_I2C_IMR_AAS BIT(6) #define DAVINCI_I2C_IMR_SCD BIT(5) #define DAVINCI_I2C_IMR_XRDY BIT(4) #define DAVINCI_I2C_IMR_RRDY BIT(3) #define DAVINCI_I2C_IMR_ARDY BIT(2) #define DAVINCI_I2C_IMR_NACK BIT(1) #define DAVINCI_I2C_IMR_AL BIT(0) struct davinci_i2c_dev { struct device *dev; Loading @@ -113,8 +107,13 @@ struct davinci_i2c_dev { u8 *buf; size_t buf_len; int irq; int stop; u8 terminate; struct i2c_adapter adapter; #ifdef CONFIG_CPU_FREQ struct completion xfr_complete; struct notifier_block freq_transition; #endif }; /* default platform data to use if not supplied in the platform_device */ Loading @@ -134,12 +133,59 @@ static inline u16 davinci_i2c_read_reg(struct davinci_i2c_dev *i2c_dev, int reg) return __raw_readw(i2c_dev->base + reg); } /* * This functions configures I2C and brings I2C out of reset. * This function is called during I2C init function. This function * also gets called if I2C encounters any errors. /* Generate a pulse on the i2c clock pin. */ static void generic_i2c_clock_pulse(unsigned int scl_pin) { u16 i; if (scl_pin) { /* Send high and low on the SCL line */ for (i = 0; i < 9; i++) { gpio_set_value(scl_pin, 0); udelay(20); gpio_set_value(scl_pin, 1); udelay(20); } } } /* This routine does i2c bus recovery as specified in the * i2c protocol Rev. 03 section 3.16 titled "Bus clear" */ static int i2c_davinci_init(struct davinci_i2c_dev *dev) static void i2c_recover_bus(struct davinci_i2c_dev *dev) { u32 flag = 0; struct davinci_i2c_platform_data *pdata = dev->dev->platform_data; dev_err(dev->dev, "initiating i2c bus recovery\n"); /* Send NACK to the slave */ flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); flag |= DAVINCI_I2C_MDR_NACK; /* write the data into mode register */ davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); if (pdata) generic_i2c_clock_pulse(pdata->scl_pin); /* Send STOP */ flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); flag |= DAVINCI_I2C_MDR_STP; davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); } static inline void davinci_i2c_reset_ctrl(struct davinci_i2c_dev *i2c_dev, int val) { u16 w; w = davinci_i2c_read_reg(i2c_dev, DAVINCI_I2C_MDR_REG); if (!val) /* put I2C into reset */ w &= ~DAVINCI_I2C_MDR_IRS; else /* take I2C out of reset */ w |= DAVINCI_I2C_MDR_IRS; davinci_i2c_write_reg(i2c_dev, DAVINCI_I2C_MDR_REG, w); } static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev) { struct davinci_i2c_platform_data *pdata = dev->dev->platform_data; u16 psc; Loading @@ -148,15 +194,6 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev) u32 clkh; u32 clkl; u32 input_clock = clk_get_rate(dev->clk); u16 w; if (!pdata) pdata = &davinci_i2c_platform_data_default; /* put I2C into reset */ w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); MOD_REG_BIT(w, DAVINCI_I2C_MDR_IRS, 0); davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w); /* NOTE: I2C Clock divider programming info * As per I2C specs the following formulas provide prescaler Loading Loading @@ -188,12 +225,32 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev) davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKH_REG, clkh); davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKL_REG, clkl); dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk); } /* * This function configures I2C and brings I2C out of reset. * This function is called during I2C init function. This function * also gets called if I2C encounters any errors. */ static int i2c_davinci_init(struct davinci_i2c_dev *dev) { struct davinci_i2c_platform_data *pdata = dev->dev->platform_data; if (!pdata) pdata = &davinci_i2c_platform_data_default; /* put I2C into reset */ davinci_i2c_reset_ctrl(dev, 0); /* compute clock dividers */ i2c_davinci_calc_clk_dividers(dev); /* Respond at reserved "SMBus Host" slave address" (and zero); * we seem to have no option to not respond... */ davinci_i2c_write_reg(dev, DAVINCI_I2C_OAR_REG, 0x08); dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk); dev_dbg(dev->dev, "PSC = %d\n", davinci_i2c_read_reg(dev, DAVINCI_I2C_PSC_REG)); dev_dbg(dev->dev, "CLKL = %d\n", Loading @@ -204,9 +261,7 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev) pdata->bus_freq, pdata->bus_delay); /* Take the I2C module out of reset: */ w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); MOD_REG_BIT(w, DAVINCI_I2C_MDR_IRS, 1); davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w); davinci_i2c_reset_ctrl(dev, 1); /* Enable interrupts */ davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, I2C_DAVINCI_INTR_ALL); Loading @@ -221,14 +276,22 @@ static int i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev, char allow_sleep) { unsigned long timeout; static u16 to_cnt; timeout = jiffies + dev->adapter.timeout; while (davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG) & DAVINCI_I2C_STR_BB) { if (to_cnt <= DAVINCI_I2C_MAX_TRIES) { if (time_after(jiffies, timeout)) { dev_warn(dev->dev, "timeout waiting for bus ready\n"); to_cnt++; return -ETIMEDOUT; } else { to_cnt = 0; i2c_recover_bus(dev); i2c_davinci_init(dev); } } if (allow_sleep) schedule_timeout(1); Loading @@ -250,9 +313,6 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) u16 w; int r; if (msg->len == 0) return -EINVAL; if (!pdata) pdata = &davinci_i2c_platform_data_default; /* Introduce a delay, required for some boards (e.g Davinci EVM) */ Loading @@ -264,6 +324,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) dev->buf = msg->buf; dev->buf_len = msg->len; dev->stop = stop; davinci_i2c_write_reg(dev, DAVINCI_I2C_CNT_REG, dev->buf_len); Loading @@ -281,23 +342,40 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) flag |= DAVINCI_I2C_MDR_TRX; if (stop) flag |= DAVINCI_I2C_MDR_STP; if (msg->len == 0) { flag |= DAVINCI_I2C_MDR_RM; flag &= ~DAVINCI_I2C_MDR_STP; } /* Enable receive or transmit interrupts */ w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG); if (msg->flags & I2C_M_RD) MOD_REG_BIT(w, DAVINCI_I2C_IMR_RRDY, 1); w |= DAVINCI_I2C_IMR_RRDY; else MOD_REG_BIT(w, DAVINCI_I2C_IMR_XRDY, 1); w |= DAVINCI_I2C_IMR_XRDY; davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, w); dev->terminate = 0; /* write the data into mode register */ davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); /* * First byte should be set here, not after interrupt, * because transmit-data-ready interrupt can come before * NACK-interrupt during sending of previous message and * ICDXR may have wrong data */ if ((!(msg->flags & I2C_M_RD)) && dev->buf_len) { davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev->buf++); dev->buf_len--; } r = wait_for_completion_interruptible_timeout(&dev->cmd_complete, dev->adapter.timeout); if (r == 0) { dev_err(dev->dev, "controller timed out\n"); i2c_recover_bus(dev); i2c_davinci_init(dev); dev->buf_len = 0; return -ETIMEDOUT; Loading Loading @@ -334,7 +412,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) return msg->len; if (stop) { w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); MOD_REG_BIT(w, DAVINCI_I2C_MDR_STP, 1); w |= DAVINCI_I2C_MDR_STP; davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w); } return -EREMOTEIO; Loading Loading @@ -367,12 +445,17 @@ i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) if (ret < 0) return ret; } #ifdef CONFIG_CPU_FREQ complete(&dev->xfr_complete); #endif return num; } static u32 i2c_davinci_func(struct i2c_adapter *adap) { return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK); return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; } static void terminate_read(struct davinci_i2c_dev *dev) Loading Loading @@ -431,6 +514,14 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id) case DAVINCI_I2C_IVR_ARDY: davinci_i2c_write_reg(dev, DAVINCI_I2C_STR_REG, DAVINCI_I2C_STR_ARDY); if (((dev->buf_len == 0) && (dev->stop != 0)) || (dev->cmd_err & DAVINCI_I2C_STR_NACK)) { w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); w |= DAVINCI_I2C_MDR_STP; davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w); } complete(&dev->cmd_complete); break; Loading Loading @@ -462,7 +553,7 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id) w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG); MOD_REG_BIT(w, DAVINCI_I2C_IMR_XRDY, 0); w &= ~DAVINCI_I2C_IMR_XRDY; davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, w); Loading Loading @@ -491,6 +582,48 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id) return count ? IRQ_HANDLED : IRQ_NONE; } #ifdef CONFIG_CPU_FREQ static int i2c_davinci_cpufreq_transition(struct notifier_block *nb, unsigned long val, void *data) { struct davinci_i2c_dev *dev; dev = container_of(nb, struct davinci_i2c_dev, freq_transition); if (val == CPUFREQ_PRECHANGE) { wait_for_completion(&dev->xfr_complete); davinci_i2c_reset_ctrl(dev, 0); } else if (val == CPUFREQ_POSTCHANGE) { i2c_davinci_calc_clk_dividers(dev); davinci_i2c_reset_ctrl(dev, 1); } return 0; } static inline int i2c_davinci_cpufreq_register(struct davinci_i2c_dev *dev) { dev->freq_transition.notifier_call = i2c_davinci_cpufreq_transition; return cpufreq_register_notifier(&dev->freq_transition, CPUFREQ_TRANSITION_NOTIFIER); } static inline void i2c_davinci_cpufreq_deregister(struct davinci_i2c_dev *dev) { cpufreq_unregister_notifier(&dev->freq_transition, CPUFREQ_TRANSITION_NOTIFIER); } #else static inline int i2c_davinci_cpufreq_register(struct davinci_i2c_dev *dev) { return 0; } static inline void i2c_davinci_cpufreq_deregister(struct davinci_i2c_dev *dev) { } #endif static struct i2c_algorithm i2c_davinci_algo = { .master_xfer = i2c_davinci_xfer, .functionality = i2c_davinci_func, Loading Loading @@ -530,6 +663,9 @@ static int davinci_i2c_probe(struct platform_device *pdev) } init_completion(&dev->cmd_complete); #ifdef CONFIG_CPU_FREQ init_completion(&dev->xfr_complete); #endif dev->dev = get_device(&pdev->dev); dev->irq = irq->start; platform_set_drvdata(pdev, dev); Loading @@ -541,7 +677,12 @@ static int davinci_i2c_probe(struct platform_device *pdev) } clk_enable(dev->clk); dev->base = (void __iomem *)IO_ADDRESS(mem->start); dev->base = ioremap(mem->start, resource_size(mem)); if (!dev->base) { r = -EBUSY; goto err_mem_ioremap; } i2c_davinci_init(dev); r = request_irq(dev->irq, i2c_davinci_isr, 0, pdev->name, dev); Loading @@ -550,6 +691,12 @@ static int davinci_i2c_probe(struct platform_device *pdev) goto err_unuse_clocks; } r = i2c_davinci_cpufreq_register(dev); if (r) { dev_err(&pdev->dev, "failed to register cpufreq\n"); goto err_free_irq; } adap = &dev->adapter; i2c_set_adapdata(adap, dev); adap->owner = THIS_MODULE; Loading @@ -571,6 +718,8 @@ static int davinci_i2c_probe(struct platform_device *pdev) err_free_irq: free_irq(dev->irq, dev); err_unuse_clocks: iounmap(dev->base); err_mem_ioremap: clk_disable(dev->clk); clk_put(dev->clk); dev->clk = NULL; Loading @@ -589,6 +738,8 @@ static int davinci_i2c_remove(struct platform_device *pdev) struct davinci_i2c_dev *dev = platform_get_drvdata(pdev); struct resource *mem; i2c_davinci_cpufreq_deregister(dev); platform_set_drvdata(pdev, NULL); i2c_del_adapter(&dev->adapter); put_device(&pdev->dev); Loading @@ -599,6 +750,7 @@ static int davinci_i2c_remove(struct platform_device *pdev) davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, 0); free_irq(IRQ_I2C, dev); iounmap(dev->base); kfree(dev); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); Loading @@ -606,6 +758,41 @@ static int davinci_i2c_remove(struct platform_device *pdev) return 0; } #ifdef CONFIG_PM static int davinci_i2c_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct davinci_i2c_dev *i2c_dev = platform_get_drvdata(pdev); /* put I2C into reset */ davinci_i2c_reset_ctrl(i2c_dev, 0); clk_disable(i2c_dev->clk); return 0; } static int davinci_i2c_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct davinci_i2c_dev *i2c_dev = platform_get_drvdata(pdev); clk_enable(i2c_dev->clk); /* take I2C out of reset */ davinci_i2c_reset_ctrl(i2c_dev, 1); return 0; } static const struct dev_pm_ops davinci_i2c_pm = { .suspend = davinci_i2c_suspend, .resume = davinci_i2c_resume, }; #define davinci_i2c_pm_ops (&davinci_i2c_pm) #else #define davinci_i2c_pm_ops NULL #endif /* work with hotplug and coldplug */ MODULE_ALIAS("platform:i2c_davinci"); Loading @@ -615,6 +802,7 @@ static struct platform_driver davinci_i2c_driver = { .driver = { .name = "i2c_davinci", .owner = THIS_MODULE, .pm = davinci_i2c_pm_ops, }, }; Loading Loading
drivers/i2c/busses/i2c-davinci.c +251 −63 Original line number Diff line number Diff line Loading @@ -36,14 +36,16 @@ #include <linux/platform_device.h> #include <linux/io.h> #include <linux/slab.h> #include <linux/cpufreq.h> #include <linux/gpio.h> #include <mach/hardware.h> #include <mach/i2c.h> /* ----- global defines ----------------------------------------------- */ #define DAVINCI_I2C_TIMEOUT (1*HZ) #define DAVINCI_I2C_MAX_TRIES 2 #define I2C_DAVINCI_INTR_ALL (DAVINCI_I2C_IMR_AAS | \ DAVINCI_I2C_IMR_SCD | \ DAVINCI_I2C_IMR_ARDY | \ Loading Loading @@ -72,37 +74,29 @@ #define DAVINCI_I2C_IVR_NACK 0x02 #define DAVINCI_I2C_IVR_AL 0x01 #define DAVINCI_I2C_STR_BB (1 << 12) #define DAVINCI_I2C_STR_RSFULL (1 << 11) #define DAVINCI_I2C_STR_SCD (1 << 5) #define DAVINCI_I2C_STR_ARDY (1 << 2) #define DAVINCI_I2C_STR_NACK (1 << 1) #define DAVINCI_I2C_STR_AL (1 << 0) #define DAVINCI_I2C_MDR_NACK (1 << 15) #define DAVINCI_I2C_MDR_STT (1 << 13) #define DAVINCI_I2C_MDR_STP (1 << 11) #define DAVINCI_I2C_MDR_MST (1 << 10) #define DAVINCI_I2C_MDR_TRX (1 << 9) #define DAVINCI_I2C_MDR_XA (1 << 8) #define DAVINCI_I2C_MDR_RM (1 << 7) #define DAVINCI_I2C_MDR_IRS (1 << 5) #define DAVINCI_I2C_IMR_AAS (1 << 6) #define DAVINCI_I2C_IMR_SCD (1 << 5) #define DAVINCI_I2C_IMR_XRDY (1 << 4) #define DAVINCI_I2C_IMR_RRDY (1 << 3) #define DAVINCI_I2C_IMR_ARDY (1 << 2) #define DAVINCI_I2C_IMR_NACK (1 << 1) #define DAVINCI_I2C_IMR_AL (1 << 0) #define MOD_REG_BIT(val, mask, set) do { \ if (set) { \ val |= mask; \ } else { \ val &= ~mask; \ } \ } while (0) #define DAVINCI_I2C_STR_BB BIT(12) #define DAVINCI_I2C_STR_RSFULL BIT(11) #define DAVINCI_I2C_STR_SCD BIT(5) #define DAVINCI_I2C_STR_ARDY BIT(2) #define DAVINCI_I2C_STR_NACK BIT(1) #define DAVINCI_I2C_STR_AL BIT(0) #define DAVINCI_I2C_MDR_NACK BIT(15) #define DAVINCI_I2C_MDR_STT BIT(13) #define DAVINCI_I2C_MDR_STP BIT(11) #define DAVINCI_I2C_MDR_MST BIT(10) #define DAVINCI_I2C_MDR_TRX BIT(9) #define DAVINCI_I2C_MDR_XA BIT(8) #define DAVINCI_I2C_MDR_RM BIT(7) #define DAVINCI_I2C_MDR_IRS BIT(5) #define DAVINCI_I2C_IMR_AAS BIT(6) #define DAVINCI_I2C_IMR_SCD BIT(5) #define DAVINCI_I2C_IMR_XRDY BIT(4) #define DAVINCI_I2C_IMR_RRDY BIT(3) #define DAVINCI_I2C_IMR_ARDY BIT(2) #define DAVINCI_I2C_IMR_NACK BIT(1) #define DAVINCI_I2C_IMR_AL BIT(0) struct davinci_i2c_dev { struct device *dev; Loading @@ -113,8 +107,13 @@ struct davinci_i2c_dev { u8 *buf; size_t buf_len; int irq; int stop; u8 terminate; struct i2c_adapter adapter; #ifdef CONFIG_CPU_FREQ struct completion xfr_complete; struct notifier_block freq_transition; #endif }; /* default platform data to use if not supplied in the platform_device */ Loading @@ -134,12 +133,59 @@ static inline u16 davinci_i2c_read_reg(struct davinci_i2c_dev *i2c_dev, int reg) return __raw_readw(i2c_dev->base + reg); } /* * This functions configures I2C and brings I2C out of reset. * This function is called during I2C init function. This function * also gets called if I2C encounters any errors. /* Generate a pulse on the i2c clock pin. */ static void generic_i2c_clock_pulse(unsigned int scl_pin) { u16 i; if (scl_pin) { /* Send high and low on the SCL line */ for (i = 0; i < 9; i++) { gpio_set_value(scl_pin, 0); udelay(20); gpio_set_value(scl_pin, 1); udelay(20); } } } /* This routine does i2c bus recovery as specified in the * i2c protocol Rev. 03 section 3.16 titled "Bus clear" */ static int i2c_davinci_init(struct davinci_i2c_dev *dev) static void i2c_recover_bus(struct davinci_i2c_dev *dev) { u32 flag = 0; struct davinci_i2c_platform_data *pdata = dev->dev->platform_data; dev_err(dev->dev, "initiating i2c bus recovery\n"); /* Send NACK to the slave */ flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); flag |= DAVINCI_I2C_MDR_NACK; /* write the data into mode register */ davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); if (pdata) generic_i2c_clock_pulse(pdata->scl_pin); /* Send STOP */ flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); flag |= DAVINCI_I2C_MDR_STP; davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); } static inline void davinci_i2c_reset_ctrl(struct davinci_i2c_dev *i2c_dev, int val) { u16 w; w = davinci_i2c_read_reg(i2c_dev, DAVINCI_I2C_MDR_REG); if (!val) /* put I2C into reset */ w &= ~DAVINCI_I2C_MDR_IRS; else /* take I2C out of reset */ w |= DAVINCI_I2C_MDR_IRS; davinci_i2c_write_reg(i2c_dev, DAVINCI_I2C_MDR_REG, w); } static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev) { struct davinci_i2c_platform_data *pdata = dev->dev->platform_data; u16 psc; Loading @@ -148,15 +194,6 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev) u32 clkh; u32 clkl; u32 input_clock = clk_get_rate(dev->clk); u16 w; if (!pdata) pdata = &davinci_i2c_platform_data_default; /* put I2C into reset */ w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); MOD_REG_BIT(w, DAVINCI_I2C_MDR_IRS, 0); davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w); /* NOTE: I2C Clock divider programming info * As per I2C specs the following formulas provide prescaler Loading Loading @@ -188,12 +225,32 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev) davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKH_REG, clkh); davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKL_REG, clkl); dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk); } /* * This function configures I2C and brings I2C out of reset. * This function is called during I2C init function. This function * also gets called if I2C encounters any errors. */ static int i2c_davinci_init(struct davinci_i2c_dev *dev) { struct davinci_i2c_platform_data *pdata = dev->dev->platform_data; if (!pdata) pdata = &davinci_i2c_platform_data_default; /* put I2C into reset */ davinci_i2c_reset_ctrl(dev, 0); /* compute clock dividers */ i2c_davinci_calc_clk_dividers(dev); /* Respond at reserved "SMBus Host" slave address" (and zero); * we seem to have no option to not respond... */ davinci_i2c_write_reg(dev, DAVINCI_I2C_OAR_REG, 0x08); dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk); dev_dbg(dev->dev, "PSC = %d\n", davinci_i2c_read_reg(dev, DAVINCI_I2C_PSC_REG)); dev_dbg(dev->dev, "CLKL = %d\n", Loading @@ -204,9 +261,7 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev) pdata->bus_freq, pdata->bus_delay); /* Take the I2C module out of reset: */ w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); MOD_REG_BIT(w, DAVINCI_I2C_MDR_IRS, 1); davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w); davinci_i2c_reset_ctrl(dev, 1); /* Enable interrupts */ davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, I2C_DAVINCI_INTR_ALL); Loading @@ -221,14 +276,22 @@ static int i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev, char allow_sleep) { unsigned long timeout; static u16 to_cnt; timeout = jiffies + dev->adapter.timeout; while (davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG) & DAVINCI_I2C_STR_BB) { if (to_cnt <= DAVINCI_I2C_MAX_TRIES) { if (time_after(jiffies, timeout)) { dev_warn(dev->dev, "timeout waiting for bus ready\n"); to_cnt++; return -ETIMEDOUT; } else { to_cnt = 0; i2c_recover_bus(dev); i2c_davinci_init(dev); } } if (allow_sleep) schedule_timeout(1); Loading @@ -250,9 +313,6 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) u16 w; int r; if (msg->len == 0) return -EINVAL; if (!pdata) pdata = &davinci_i2c_platform_data_default; /* Introduce a delay, required for some boards (e.g Davinci EVM) */ Loading @@ -264,6 +324,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) dev->buf = msg->buf; dev->buf_len = msg->len; dev->stop = stop; davinci_i2c_write_reg(dev, DAVINCI_I2C_CNT_REG, dev->buf_len); Loading @@ -281,23 +342,40 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) flag |= DAVINCI_I2C_MDR_TRX; if (stop) flag |= DAVINCI_I2C_MDR_STP; if (msg->len == 0) { flag |= DAVINCI_I2C_MDR_RM; flag &= ~DAVINCI_I2C_MDR_STP; } /* Enable receive or transmit interrupts */ w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG); if (msg->flags & I2C_M_RD) MOD_REG_BIT(w, DAVINCI_I2C_IMR_RRDY, 1); w |= DAVINCI_I2C_IMR_RRDY; else MOD_REG_BIT(w, DAVINCI_I2C_IMR_XRDY, 1); w |= DAVINCI_I2C_IMR_XRDY; davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, w); dev->terminate = 0; /* write the data into mode register */ davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag); /* * First byte should be set here, not after interrupt, * because transmit-data-ready interrupt can come before * NACK-interrupt during sending of previous message and * ICDXR may have wrong data */ if ((!(msg->flags & I2C_M_RD)) && dev->buf_len) { davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev->buf++); dev->buf_len--; } r = wait_for_completion_interruptible_timeout(&dev->cmd_complete, dev->adapter.timeout); if (r == 0) { dev_err(dev->dev, "controller timed out\n"); i2c_recover_bus(dev); i2c_davinci_init(dev); dev->buf_len = 0; return -ETIMEDOUT; Loading Loading @@ -334,7 +412,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop) return msg->len; if (stop) { w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); MOD_REG_BIT(w, DAVINCI_I2C_MDR_STP, 1); w |= DAVINCI_I2C_MDR_STP; davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w); } return -EREMOTEIO; Loading Loading @@ -367,12 +445,17 @@ i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) if (ret < 0) return ret; } #ifdef CONFIG_CPU_FREQ complete(&dev->xfr_complete); #endif return num; } static u32 i2c_davinci_func(struct i2c_adapter *adap) { return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK); return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; } static void terminate_read(struct davinci_i2c_dev *dev) Loading Loading @@ -431,6 +514,14 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id) case DAVINCI_I2C_IVR_ARDY: davinci_i2c_write_reg(dev, DAVINCI_I2C_STR_REG, DAVINCI_I2C_STR_ARDY); if (((dev->buf_len == 0) && (dev->stop != 0)) || (dev->cmd_err & DAVINCI_I2C_STR_NACK)) { w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG); w |= DAVINCI_I2C_MDR_STP; davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w); } complete(&dev->cmd_complete); break; Loading Loading @@ -462,7 +553,7 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id) w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG); MOD_REG_BIT(w, DAVINCI_I2C_IMR_XRDY, 0); w &= ~DAVINCI_I2C_IMR_XRDY; davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, w); Loading Loading @@ -491,6 +582,48 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id) return count ? IRQ_HANDLED : IRQ_NONE; } #ifdef CONFIG_CPU_FREQ static int i2c_davinci_cpufreq_transition(struct notifier_block *nb, unsigned long val, void *data) { struct davinci_i2c_dev *dev; dev = container_of(nb, struct davinci_i2c_dev, freq_transition); if (val == CPUFREQ_PRECHANGE) { wait_for_completion(&dev->xfr_complete); davinci_i2c_reset_ctrl(dev, 0); } else if (val == CPUFREQ_POSTCHANGE) { i2c_davinci_calc_clk_dividers(dev); davinci_i2c_reset_ctrl(dev, 1); } return 0; } static inline int i2c_davinci_cpufreq_register(struct davinci_i2c_dev *dev) { dev->freq_transition.notifier_call = i2c_davinci_cpufreq_transition; return cpufreq_register_notifier(&dev->freq_transition, CPUFREQ_TRANSITION_NOTIFIER); } static inline void i2c_davinci_cpufreq_deregister(struct davinci_i2c_dev *dev) { cpufreq_unregister_notifier(&dev->freq_transition, CPUFREQ_TRANSITION_NOTIFIER); } #else static inline int i2c_davinci_cpufreq_register(struct davinci_i2c_dev *dev) { return 0; } static inline void i2c_davinci_cpufreq_deregister(struct davinci_i2c_dev *dev) { } #endif static struct i2c_algorithm i2c_davinci_algo = { .master_xfer = i2c_davinci_xfer, .functionality = i2c_davinci_func, Loading Loading @@ -530,6 +663,9 @@ static int davinci_i2c_probe(struct platform_device *pdev) } init_completion(&dev->cmd_complete); #ifdef CONFIG_CPU_FREQ init_completion(&dev->xfr_complete); #endif dev->dev = get_device(&pdev->dev); dev->irq = irq->start; platform_set_drvdata(pdev, dev); Loading @@ -541,7 +677,12 @@ static int davinci_i2c_probe(struct platform_device *pdev) } clk_enable(dev->clk); dev->base = (void __iomem *)IO_ADDRESS(mem->start); dev->base = ioremap(mem->start, resource_size(mem)); if (!dev->base) { r = -EBUSY; goto err_mem_ioremap; } i2c_davinci_init(dev); r = request_irq(dev->irq, i2c_davinci_isr, 0, pdev->name, dev); Loading @@ -550,6 +691,12 @@ static int davinci_i2c_probe(struct platform_device *pdev) goto err_unuse_clocks; } r = i2c_davinci_cpufreq_register(dev); if (r) { dev_err(&pdev->dev, "failed to register cpufreq\n"); goto err_free_irq; } adap = &dev->adapter; i2c_set_adapdata(adap, dev); adap->owner = THIS_MODULE; Loading @@ -571,6 +718,8 @@ static int davinci_i2c_probe(struct platform_device *pdev) err_free_irq: free_irq(dev->irq, dev); err_unuse_clocks: iounmap(dev->base); err_mem_ioremap: clk_disable(dev->clk); clk_put(dev->clk); dev->clk = NULL; Loading @@ -589,6 +738,8 @@ static int davinci_i2c_remove(struct platform_device *pdev) struct davinci_i2c_dev *dev = platform_get_drvdata(pdev); struct resource *mem; i2c_davinci_cpufreq_deregister(dev); platform_set_drvdata(pdev, NULL); i2c_del_adapter(&dev->adapter); put_device(&pdev->dev); Loading @@ -599,6 +750,7 @@ static int davinci_i2c_remove(struct platform_device *pdev) davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, 0); free_irq(IRQ_I2C, dev); iounmap(dev->base); kfree(dev); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); Loading @@ -606,6 +758,41 @@ static int davinci_i2c_remove(struct platform_device *pdev) return 0; } #ifdef CONFIG_PM static int davinci_i2c_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct davinci_i2c_dev *i2c_dev = platform_get_drvdata(pdev); /* put I2C into reset */ davinci_i2c_reset_ctrl(i2c_dev, 0); clk_disable(i2c_dev->clk); return 0; } static int davinci_i2c_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct davinci_i2c_dev *i2c_dev = platform_get_drvdata(pdev); clk_enable(i2c_dev->clk); /* take I2C out of reset */ davinci_i2c_reset_ctrl(i2c_dev, 1); return 0; } static const struct dev_pm_ops davinci_i2c_pm = { .suspend = davinci_i2c_suspend, .resume = davinci_i2c_resume, }; #define davinci_i2c_pm_ops (&davinci_i2c_pm) #else #define davinci_i2c_pm_ops NULL #endif /* work with hotplug and coldplug */ MODULE_ALIAS("platform:i2c_davinci"); Loading @@ -615,6 +802,7 @@ static struct platform_driver davinci_i2c_driver = { .driver = { .name = "i2c_davinci", .owner = THIS_MODULE, .pm = davinci_i2c_pm_ops, }, }; Loading