Lines Matching refs:i2c

5  * Code portions referenced from the i2x-pxa and i2c-pnx drivers
17 #include <linux/i2c.h>
83 static void i2c_lpc2k_reset(struct lpc2k_i2c *i2c)
86 writel(LPC24XX_CLEAR_ALL, i2c->base + LPC24XX_I2CONCLR);
87 writel(0, i2c->base + LPC24XX_I2ADDR);
88 writel(LPC24XX_I2EN, i2c->base + LPC24XX_I2CONSET);
91 static int i2c_lpc2k_clear_arb(struct lpc2k_i2c *i2c)
99 writel(LPC24XX_STO, i2c->base + LPC24XX_I2CONSET);
102 while (readl(i2c->base + LPC24XX_I2STAT) != M_I2C_IDLE) {
105 i2c_lpc2k_reset(i2c);
115 static void i2c_lpc2k_pump_msg(struct lpc2k_i2c *i2c)
124 status = readl(i2c->base + LPC24XX_I2STAT);
130 data = i2c_8bit_addr_from_msg(i2c->msg);
132 writel(data, i2c->base + LPC24XX_I2DAT);
133 writel(LPC24XX_STA, i2c->base + LPC24XX_I2CONCLR);
142 if (i2c->msg_idx < i2c->msg->len) {
143 writel(i2c->msg->buf[i2c->msg_idx],
144 i2c->base + LPC24XX_I2DAT);
145 } else if (i2c->is_last) {
147 writel(LPC24XX_STO_AA, i2c->base + LPC24XX_I2CONSET);
148 writel(LPC24XX_SI, i2c->base + LPC24XX_I2CONCLR);
149 i2c->msg_status = 0;
150 disable_irq_nosync(i2c->irq);
152 i2c->msg_status = 0;
153 disable_irq_nosync(i2c->irq);
156 i2c->msg_idx++;
161 if (i2c->msg->len == 1) {
163 writel(LPC24XX_AA, i2c->base + LPC24XX_I2CONCLR);
166 writel(LPC24XX_AA, i2c->base + LPC24XX_I2CONSET);
169 writel(LPC24XX_STA, i2c->base + LPC24XX_I2CONCLR);
180 if (i2c->msg_idx < i2c->msg->len) {
181 i2c->msg->buf[i2c->msg_idx] =
182 readl(i2c->base + LPC24XX_I2DAT);
186 if (i2c->msg_idx >= i2c->msg->len - 1 && i2c->is_last) {
187 writel(LPC24XX_STO_AA, i2c->base + LPC24XX_I2CONSET);
188 writel(LPC24XX_SI, i2c->base + LPC24XX_I2CONCLR);
189 i2c->msg_status = 0;
193 if (i2c->msg_idx >= i2c->msg->len - 1) {
194 i2c->msg_status = 0;
195 disable_irq_nosync(i2c->irq);
202 if (i2c->msg_idx >= i2c->msg->len - 2) {
204 writel(LPC24XX_AA, i2c->base + LPC24XX_I2CONCLR);
207 writel(LPC24XX_AA, i2c->base + LPC24XX_I2CONSET);
210 writel(LPC24XX_STA, i2c->base + LPC24XX_I2CONCLR);
211 i2c->msg_idx++;
218 writel(LPC24XX_STO_AA, i2c->base + LPC24XX_I2CONSET);
219 i2c->msg_status = -ENXIO;
220 disable_irq_nosync(i2c->irq);
225 i2c->msg_status = -EAGAIN;
228 writel(LPC24XX_STA | LPC24XX_STO, i2c->base + LPC24XX_I2CONCLR);
229 disable_irq_nosync(i2c->irq);
234 i2c->msg_status = -EIO;
235 disable_irq_nosync(i2c->irq);
240 if (i2c->msg_status != -EBUSY)
241 wake_up(&i2c->wait);
247 if (i2c->msg_status != 0)
248 writel(LPC24XX_SI, i2c->base + LPC24XX_I2CONCLR);
251 static int lpc2k_process_msg(struct lpc2k_i2c *i2c, int msgidx)
255 writel(LPC24XX_STA, i2c->base + LPC24XX_I2CONSET);
262 if (unlikely(i2c->msg->flags & I2C_M_NOSTART)) {
263 WARN_ON(i2c->msg->len == 0);
265 if (!(i2c->msg->flags & I2C_M_RD)) {
267 writel(i2c->msg->buf[0],
268 i2c->base + LPC24XX_I2DAT);
269 i2c->msg_idx++;
273 writel(LPC24XX_STA, i2c->base + LPC24XX_I2CONSET);
276 writel(LPC24XX_SI, i2c->base + LPC24XX_I2CONCLR);
279 enable_irq(i2c->irq);
282 if (wait_event_timeout(i2c->wait, i2c->msg_status != -EBUSY,
284 disable_irq_nosync(i2c->irq);
289 return i2c->msg_status;
295 struct lpc2k_i2c *i2c = i2c_get_adapdata(adap);
300 stat = readl(i2c->base + LPC24XX_I2STAT);
303 return i2c_lpc2k_clear_arb(i2c);
309 i2c->msg = &msgs[i];
310 i2c->msg_idx = 0;
311 i2c->msg_status = -EBUSY;
312 i2c->is_last = (i == (msg_num - 1));
314 ret = lpc2k_process_msg(i2c, i);
324 struct lpc2k_i2c *i2c = dev_id;
326 if (readl(i2c->base + LPC24XX_I2CONSET) & LPC24XX_SI) {
327 i2c_lpc2k_pump_msg(i2c);
347 struct lpc2k_i2c *i2c;
353 i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
354 if (!i2c)
357 i2c->base = devm_platform_ioremap_resource(pdev, 0);
358 if (IS_ERR(i2c->base))
359 return PTR_ERR(i2c->base);
361 i2c->irq = platform_get_irq(pdev, 0);
362 if (i2c->irq < 0)
363 return i2c->irq;
365 init_waitqueue_head(&i2c->wait);
367 i2c->clk = devm_clk_get_enabled(&pdev->dev, NULL);
368 if (IS_ERR(i2c->clk)) {
370 return PTR_ERR(i2c->clk);
373 ret = devm_request_irq(&pdev->dev, i2c->irq, i2c_lpc2k_handler, 0,
374 dev_name(&pdev->dev), i2c);
380 disable_irq_nosync(i2c->irq);
383 i2c_lpc2k_reset(i2c);
390 clkrate = clk_get_rate(i2c->clk);
405 writel(scl_high, i2c->base + LPC24XX_I2SCLH);
406 writel(clkrate - scl_high, i2c->base + LPC24XX_I2SCLL);
408 platform_set_drvdata(pdev, i2c);
410 i2c_set_adapdata(&i2c->adap, i2c);
411 i2c->adap.owner = THIS_MODULE;
412 strscpy(i2c->adap.name, "LPC2K I2C adapter", sizeof(i2c->adap.name));
413 i2c->adap.algo = &i2c_lpc2k_algorithm;
414 i2c->adap.dev.parent = &pdev->dev;
415 i2c->adap.dev.of_node = pdev->dev.of_node;
417 ret = i2c_add_adapter(&i2c->adap);
428 struct lpc2k_i2c *i2c = platform_get_drvdata(dev);
430 i2c_del_adapter(&i2c->adap);
435 struct lpc2k_i2c *i2c = dev_get_drvdata(dev);
437 clk_disable(i2c->clk);
444 struct lpc2k_i2c *i2c = dev_get_drvdata(dev);
446 clk_enable(i2c->clk);
447 i2c_lpc2k_reset(i2c);
458 { .compatible = "nxp,lpc1788-i2c" },
467 .name = "lpc2k-i2c",
477 MODULE_ALIAS("platform:lpc2k-i2c");