Skip to content

Commit b7a3670

Browse files
Mike RapoportJean Delvare
authored andcommitted
i2c-pxa: Add polling transfer
Add polling I2C transfer implementation for PXA I2C. This is needed for cases where I2C transactions have to occur at times interrups are disabled. Signed-off-by: Mike Rapoport <mike@compulab.co.il> Acked-by: eric miao <eric.miao@marvell.com> Signed-off-by: Jean Delvare <khali@linux-fr.org>
1 parent cea443a commit b7a3670

File tree

3 files changed

+133
-12
lines changed

3 files changed

+133
-12
lines changed

arch/arm/mach-pxa/pxa27x.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <asm/arch/ohci.h>
2525
#include <asm/arch/pm.h>
2626
#include <asm/arch/dma.h>
27+
#include <asm/arch/i2c.h>
2728

2829
#include "generic.h"
2930
#include "devices.h"
@@ -423,6 +424,11 @@ struct platform_device pxa27x_device_i2c_power = {
423424
.num_resources = ARRAY_SIZE(i2c_power_resources),
424425
};
425426

427+
void __init pxa_set_i2c_power_info(struct i2c_pxa_platform_data *info)
428+
{
429+
pxa27x_device_i2c_power.dev.platform_data = info;
430+
}
431+
426432
static struct platform_device *devices[] __initdata = {
427433
&pxa_device_mci,
428434
&pxa_device_udc,

drivers/i2c/busses/i2c-pxa.c

Lines changed: 121 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ struct pxa_i2c {
6565
unsigned long iosize;
6666

6767
int irq;
68+
int use_pio;
6869
};
6970

7071
#define _IBMR(i2c) ((i2c)->reg_base + 0)
@@ -163,6 +164,7 @@ static void i2c_pxa_show_state(struct pxa_i2c *i2c, int lno, const char *fname)
163164
#define eedbg(lvl, x...) do { if ((lvl) < 1) { printk(KERN_DEBUG "" x); } } while(0)
164165

165166
static void i2c_pxa_master_complete(struct pxa_i2c *i2c, int ret);
167+
static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id);
166168

167169
static void i2c_pxa_scream_blue_murder(struct pxa_i2c *i2c, const char *why)
168170
{
@@ -554,6 +556,71 @@ static inline void i2c_pxa_stop_message(struct pxa_i2c *i2c)
554556
writel(icr, _ICR(i2c));
555557
}
556558

559+
static int i2c_pxa_pio_set_master(struct pxa_i2c *i2c)
560+
{
561+
/* make timeout the same as for interrupt based functions */
562+
long timeout = 2 * DEF_TIMEOUT;
563+
564+
/*
565+
* Wait for the bus to become free.
566+
*/
567+
while (timeout-- && readl(_ISR(i2c)) & (ISR_IBB | ISR_UB)) {
568+
udelay(1000);
569+
show_state(i2c);
570+
}
571+
572+
if (timeout <= 0) {
573+
show_state(i2c);
574+
dev_err(&i2c->adap.dev,
575+
"i2c_pxa: timeout waiting for bus free\n");
576+
return I2C_RETRY;
577+
}
578+
579+
/*
580+
* Set master mode.
581+
*/
582+
writel(readl(_ICR(i2c)) | ICR_SCLE, _ICR(i2c));
583+
584+
return 0;
585+
}
586+
587+
static int i2c_pxa_do_pio_xfer(struct pxa_i2c *i2c,
588+
struct i2c_msg *msg, int num)
589+
{
590+
unsigned long timeout = 500000; /* 5 seconds */
591+
int ret = 0;
592+
593+
ret = i2c_pxa_pio_set_master(i2c);
594+
if (ret)
595+
goto out;
596+
597+
i2c->msg = msg;
598+
i2c->msg_num = num;
599+
i2c->msg_idx = 0;
600+
i2c->msg_ptr = 0;
601+
i2c->irqlogidx = 0;
602+
603+
i2c_pxa_start_message(i2c);
604+
605+
while (timeout-- && i2c->msg_num > 0) {
606+
i2c_pxa_handler(0, i2c);
607+
udelay(10);
608+
}
609+
610+
i2c_pxa_stop_message(i2c);
611+
612+
/*
613+
* We place the return code in i2c->msg_idx.
614+
*/
615+
ret = i2c->msg_idx;
616+
617+
out:
618+
if (timeout == 0)
619+
i2c_pxa_scream_blue_murder(i2c, "timeout");
620+
621+
return ret;
622+
}
623+
557624
/*
558625
* We are protected by the adapter bus mutex.
559626
*/
@@ -610,6 +677,35 @@ static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num)
610677
return ret;
611678
}
612679

680+
static int i2c_pxa_pio_xfer(struct i2c_adapter *adap,
681+
struct i2c_msg msgs[], int num)
682+
{
683+
struct pxa_i2c *i2c = adap->algo_data;
684+
int ret, i;
685+
686+
/* If the I2C controller is disabled we need to reset it
687+
(probably due to a suspend/resume destroying state). We do
688+
this here as we can then avoid worrying about resuming the
689+
controller before its users. */
690+
if (!(readl(_ICR(i2c)) & ICR_IUE))
691+
i2c_pxa_reset(i2c);
692+
693+
for (i = adap->retries; i >= 0; i--) {
694+
ret = i2c_pxa_do_pio_xfer(i2c, msgs, num);
695+
if (ret != I2C_RETRY)
696+
goto out;
697+
698+
if (i2c_debug)
699+
dev_dbg(&adap->dev, "Retrying transmission\n");
700+
udelay(100);
701+
}
702+
i2c_pxa_scream_blue_murder(i2c, "exhausted retries");
703+
ret = -EREMOTEIO;
704+
out:
705+
i2c_pxa_set_slave(i2c, ret);
706+
return ret;
707+
}
708+
613709
/*
614710
* i2c_pxa_master_complete - complete the message and wake up.
615711
*/
@@ -621,7 +717,8 @@ static void i2c_pxa_master_complete(struct pxa_i2c *i2c, int ret)
621717
i2c->msg_num = 0;
622718
if (ret)
623719
i2c->msg_idx = ret;
624-
wake_up(&i2c->wait);
720+
if (!i2c->use_pio)
721+
wake_up(&i2c->wait);
625722
}
626723

627724
static void i2c_pxa_irq_txempty(struct pxa_i2c *i2c, u32 isr)
@@ -840,6 +937,11 @@ static const struct i2c_algorithm i2c_pxa_algorithm = {
840937
.functionality = i2c_pxa_functionality,
841938
};
842939

940+
static const struct i2c_algorithm i2c_pxa_pio_algorithm = {
941+
.master_xfer = i2c_pxa_pio_xfer,
942+
.functionality = i2c_pxa_functionality,
943+
};
944+
843945
static void i2c_pxa_enable(struct platform_device *dev)
844946
{
845947
if (cpu_is_pxa27x()) {
@@ -890,7 +992,6 @@ static int i2c_pxa_probe(struct platform_device *dev)
890992
}
891993

892994
i2c->adap.owner = THIS_MODULE;
893-
i2c->adap.algo = &i2c_pxa_algorithm;
894995
i2c->adap.retries = 5;
895996

896997
spin_lock_init(&i2c->lock);
@@ -927,20 +1028,26 @@ static int i2c_pxa_probe(struct platform_device *dev)
9271028
clk_enable(i2c->clk);
9281029
i2c_pxa_enable(dev);
9291030

930-
ret = request_irq(irq, i2c_pxa_handler, IRQF_DISABLED,
931-
i2c->adap.name, i2c);
932-
if (ret)
933-
goto ereqirq;
1031+
if (plat) {
1032+
i2c->adap.class = plat->class;
1033+
i2c->use_pio = plat->use_pio;
1034+
}
1035+
1036+
if (i2c->use_pio) {
1037+
i2c->adap.algo = &i2c_pxa_pio_algorithm;
1038+
} else {
1039+
i2c->adap.algo = &i2c_pxa_algorithm;
1040+
ret = request_irq(irq, i2c_pxa_handler, IRQF_DISABLED,
1041+
i2c->adap.name, i2c);
1042+
if (ret)
1043+
goto ereqirq;
1044+
}
9341045

9351046
i2c_pxa_reset(i2c);
9361047

9371048
i2c->adap.algo_data = i2c;
9381049
i2c->adap.dev.parent = &dev->dev;
9391050

940-
if (plat) {
941-
i2c->adap.class = plat->class;
942-
}
943-
9441051
/*
9451052
* If "dev->id" is negative we consider it as zero.
9461053
* The reason to do so is to avoid sysfs names that only make
@@ -966,7 +1073,8 @@ static int i2c_pxa_probe(struct platform_device *dev)
9661073
return 0;
9671074

9681075
eadapt:
969-
free_irq(irq, i2c);
1076+
if (!i2c->use_pio)
1077+
free_irq(irq, i2c);
9701078
ereqirq:
9711079
clk_disable(i2c->clk);
9721080
i2c_pxa_disable(dev);
@@ -986,7 +1094,8 @@ static int i2c_pxa_remove(struct platform_device *dev)
9861094
platform_set_drvdata(dev, NULL);
9871095

9881096
i2c_del_adapter(&i2c->adap);
989-
free_irq(i2c->irq, i2c);
1097+
if (!i2c->use_pio)
1098+
free_irq(i2c->irq, i2c);
9901099

9911100
clk_disable(i2c->clk);
9921101
clk_put(i2c->clk);

include/asm-arm/arch-pxa/i2c.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,13 @@ struct i2c_pxa_platform_data {
6565
unsigned int slave_addr;
6666
struct i2c_slave_client *slave;
6767
unsigned int class;
68+
int use_pio;
6869
};
6970

7071
extern void pxa_set_i2c_info(struct i2c_pxa_platform_data *info);
72+
73+
#ifdef CONFIG_PXA27x
74+
extern void pxa_set_i2c_power_info(struct i2c_pxa_platform_data *info);
75+
#endif
76+
7177
#endif

0 commit comments

Comments
 (0)