12 #include <linux/kernel.h>
13 #include <linux/slab.h>
14 #include <linux/module.h>
16 #include <linux/i2c.h>
28 #define MV64XXX_I2C_REG_SLAVE_ADDR 0x00
29 #define MV64XXX_I2C_REG_DATA 0x04
30 #define MV64XXX_I2C_REG_CONTROL 0x08
31 #define MV64XXX_I2C_REG_STATUS 0x0c
32 #define MV64XXX_I2C_REG_BAUD 0x0c
33 #define MV64XXX_I2C_REG_EXT_SLAVE_ADDR 0x10
34 #define MV64XXX_I2C_REG_SOFT_RESET 0x1c
36 #define MV64XXX_I2C_REG_CONTROL_ACK 0x00000004
37 #define MV64XXX_I2C_REG_CONTROL_IFLG 0x00000008
38 #define MV64XXX_I2C_REG_CONTROL_STOP 0x00000010
39 #define MV64XXX_I2C_REG_CONTROL_START 0x00000020
40 #define MV64XXX_I2C_REG_CONTROL_TWSIEN 0x00000040
41 #define MV64XXX_I2C_REG_CONTROL_INTEN 0x00000080
44 #define MV64XXX_I2C_STATUS_BUS_ERR 0x00
45 #define MV64XXX_I2C_STATUS_MAST_START 0x08
46 #define MV64XXX_I2C_STATUS_MAST_REPEAT_START 0x10
47 #define MV64XXX_I2C_STATUS_MAST_WR_ADDR_ACK 0x18
48 #define MV64XXX_I2C_STATUS_MAST_WR_ADDR_NO_ACK 0x20
49 #define MV64XXX_I2C_STATUS_MAST_WR_ACK 0x28
50 #define MV64XXX_I2C_STATUS_MAST_WR_NO_ACK 0x30
51 #define MV64XXX_I2C_STATUS_MAST_LOST_ARB 0x38
52 #define MV64XXX_I2C_STATUS_MAST_RD_ADDR_ACK 0x40
53 #define MV64XXX_I2C_STATUS_MAST_RD_ADDR_NO_ACK 0x48
54 #define MV64XXX_I2C_STATUS_MAST_RD_DATA_ACK 0x50
55 #define MV64XXX_I2C_STATUS_MAST_RD_DATA_NO_ACK 0x58
56 #define MV64XXX_I2C_STATUS_MAST_WR_ADDR_2_ACK 0xd0
57 #define MV64XXX_I2C_STATUS_MAST_WR_ADDR_2_NO_ACK 0xd8
58 #define MV64XXX_I2C_STATUS_MAST_RD_ADDR_2_ACK 0xe0
59 #define MV64XXX_I2C_STATUS_MAST_RD_ADDR_2_NO_ACK 0xe8
60 #define MV64XXX_I2C_STATUS_NO_STATUS 0xf8
106 #if defined(CONFIG_HAVE_CLK)
235 "mv64xxx_i2c_fsm: Ctlr Error -- state: 0x%x, "
236 "status: 0x%x, addr: 0x%x, flags: 0x%x\n",
237 drv_data->
state, status, drv_data->
msg->addr,
238 drv_data->
msg->flags);
240 mv64xxx_i2c_hw_init(drv_data);
248 switch(drv_data->
action) {
309 "mv64xxx_i2c_do_action: Invalid action: %d\n",
324 mv64xxx_i2c_intr(
int irq,
void *
dev_id)
335 mv64xxx_i2c_fsm(drv_data, status);
336 mv64xxx_i2c_do_action(drv_data);
339 spin_unlock_irqrestore(&drv_data->
lock, flags);
369 drv_data->
addr1 = 0xf0 | (((
u32)msg->
addr & 0x300) >> 7) | dir;
391 }
else if (time_left < 0) {
392 drv_data->
rc = time_left;
396 if (abort && drv_data->
block) {
398 spin_unlock_irqrestore(&drv_data->
lock, flags);
403 if ((time_left <= 0) && drv_data->
block) {
406 "mv64xxx: I2C bus locked, block: %d, "
407 "time_left: %d\n", drv_data->
block,
409 mv64xxx_i2c_hw_init(drv_data);
412 spin_unlock_irqrestore(&drv_data->
lock, flags);
417 int is_first,
int is_last)
422 mv64xxx_i2c_prepare_for_io(drv_data, msg);
450 mv64xxx_i2c_do_action(drv_data);
451 spin_unlock_irqrestore(&drv_data->
lock, flags);
453 mv64xxx_i2c_wait_for_completion(drv_data);
465 mv64xxx_i2c_functionality(
struct i2c_adapter *adap)
476 for (i = 0; i < num; i++) {
477 rc = mv64xxx_i2c_execute_msg(drv_data, &msgs[i],
478 i == 0, i + 1 == num);
487 .master_xfer = mv64xxx_i2c_xfer,
488 .functionality = mv64xxx_i2c_functionality,
508 size = resource_size(r);
534 mv64xxx_calc_freq(
const int tclk,
const int n,
const int m)
536 return tclk / (10 * (m + 1) * (2 << n));
546 for (n = 0; n <= 7; n++)
547 for (m = 0; m <= 15; m++) {
548 freq = mv64xxx_calc_freq(tclk, n, m);
549 delta = req_freq -
freq;
550 if (delta >= 0 && delta < best_delta) {
574 #if !defined(CONFIG_HAVE_CLK)
578 if (IS_ERR(drv_data->clk)) {
583 of_property_read_u32(np,
"clock-frequency", &bus_freq);
584 if (!mv64xxx_find_baud_factors(bus_freq, tclk,
615 if ((!pdata && !pd->
dev.of_node))
622 if (mv64xxx_i2c_map_regs(pd, drv_data)) {
628 sizeof(drv_data->
adapter.name));
633 #if defined(CONFIG_HAVE_CLK)
636 if (!IS_ERR(drv_data->clk)) {
646 }
else if (pd->
dev.of_node) {
647 rc = mv64xxx_of_config(drv_data, pd->
dev.of_node);
649 goto exit_unmap_regs;
651 if (drv_data->
irq < 0) {
653 goto exit_unmap_regs;
657 drv_data->
adapter.algo = &mv64xxx_i2c_algo;
661 drv_data->
adapter.dev.of_node = pd->
dev.of_node;
662 platform_set_drvdata(pd, drv_data);
663 i2c_set_adapdata(&drv_data->
adapter, drv_data);
665 mv64xxx_i2c_hw_init(drv_data);
670 "mv64xxx: Can't register intr handler irq: %d\n",
673 goto exit_unmap_regs;
676 "mv64xxx: Can't add i2c adapter, rc: %d\n", -rc);
687 #if defined(CONFIG_HAVE_CLK)
689 if (!IS_ERR(drv_data->clk)) {
694 mv64xxx_i2c_unmap_regs(drv_data);
708 mv64xxx_i2c_unmap_regs(drv_data);
709 #if defined(CONFIG_HAVE_CLK)
711 if (!IS_ERR(drv_data->clk)) {
722 { .compatible =
"marvell,mv64xxx-i2c", },
728 .probe = mv64xxx_i2c_probe,
733 .of_match_table =
of_match_ptr(mv64xxx_i2c_of_match_table),