I2C总线设备注册过程

转自

http://lhsblog01.blog.163.com/blog/static/1020045192010221103944423/i2c bus

i2c总线使用 platform_device实现, 总线驱动用platform_driver实现.
在注册i2c_bus时,会把与这个BUS相连的所有设备记录到全局变量中,再配置 mux register打开sda, scl .最向内核注册BUS的platform.

当加载i2c总线驱动时,匹配到上面的i2c总线后(platform_device)。 会回调其probe函数, 里面会产生adapter,并注册。在注册的过程最后会创建 记录在 全局变量中的对应于这个adapter的设备(即是这个i2c总线的设备):i2c_client.(并添加到adapter中)

然后当加载 i2c_driver时,就会自动地匹配到其i2c_client.

//***********************

0: 添加i2c总线设备:注册i2c_bus:实现为一个 platform device: pdev, 注册时要设置 Mux, 即改写 控制 register. 同时添加到i2c 板上设备信息列表。 ==> i2c.c
添加板上设备信息:omap_register_i2c_bus --> i2c_register_board_info(bus_id, info, len); 
== > list_add_tail(&devinfo->list, &__i2c_board_list);

1: 注册i2c总线驱动: 实现为一个 platform_driver,  probe中创建一个 omap_i2c_dev: dev,内含新生成的 adapter:adap结构。  ==> i2c-omap.c
连接:
dev->dev = &pdev->dev;
adapter->dev->driver_da ta = dev.
pdev->dev->driver_da ta = dev
      最后注册这个 adapter.  adapter->dev->parent = pdev->dev  ==> i2c_register_adapter(adap);
在注册的过程中:i2c_scan_static_board_info(adap); ==> 这里会创建出代表与这个adapter关联的所有i2c_client.即i2c总线上的所有设备。[如twl4030]
总线上的设备在添加总线时,添加到了:__i2c_board_list:[board_info]
从而代表整个 i2c总线的  omap_i2c_dev 与 总线的设备platform_device表示 关联。

2: 注册从设备的驱动: i2c_driver(twl4030),注册时匹配adapter注册时创建的i2c_client,然后probe创建其子从设备为i2c_client。 ==> twl4030-core.c
为每个子设备创建对应的 i2c_client: 并存入到自己的全局变量中: twl4030_modules[]:为i2c通信服务。
然后生成每个子设备的 platform_device, 并注册到内核中(使用通用设备模型的方法)。platform_device的父设备(parent)是 i2c_client 's dev 
产生子设备的方法:
方法1: 通用设备模型的方式:bus_type, driver_register, driver_attach==> probe.   OMAP3 实现的方式就是这个, 在probe中创建所有的子从设备(i2c_client)及platform_device
方法2:会从内核中匹配所有的 adapter:__attach_adapter.=> i2c_detect
另,其在add_children中,根据i2c_bus1的 platform_device's platform_da ta 添加了其所有 子设备的platform_device,并放进了对应的platform_device.

3: 子从设备(keypad)的驱动加载:
实现为 platform_driver,注册时,会匹配到其 由twl4030(add_children)根据 i2c给的资源创建的: platform_device。 从而从中得到所要的资源。
其中断处理函数, 会从keypad的ID角度(功能num)去调用 twl4030的接口。twl4030设备的驱动去调用 下层 i2c总线提供的 传输方法(adapter, xfer)。
twl4030_modules[] : 子设备的 i2c_client
twl4030_map : 子设备id 及 基址。

?????问题,
是如何回调那个 twl4030 的probe的。。。那时好像还没有 i2c_client(i2c_adapter: i2c1_bus上)。。。。
*/

从子设备调用 其下层的 接口: 传入 功能num.
共有四个模块,每个模块都有几个不同的(功能)地址,
#define TWL4030_MODULE_KEYPAD xx   //slave num: 所有的功能num.
struct twl4030mapping {/* mapping the module id to slave id and base address */
unsigned char sid; /* Slave ID */
unsigned char base; /* base address */
};
u8 mod_no ==> 功能num
sid = twl4030_map[mod_no].sid;
twl = &twl4030_modules[sid];





//***********************-1 ************************//
static struct i2c_board_info __initdata zoom2_i2c_bus1_info[] = {
{
I2C_BOARD_INFO("twl4030", 0x48),
.flags = I2C_CLIENT_WAKE,
.irq = INT_34XX_SYS_NIRQ,
.platform_da ta = &zoom2_twldata,
},
};
static int __init omap_i2c_init(void)
{
omap_register_i2c_bus(1, 100, zoom2_i2c_bus1_info,
ARRAY_SIZE(zoom2_i2c_bus1_info));
omap_register_i2c_bus(2, 100, zoom2_i2c_bus2_info,
ARRAY_SIZE(zoom2_i2c_bus2_info));
omap_register_i2c_bus(3, 400, zoom2_i2c_bus3_info,
ARRAY_SIZE(zoom2_i2c_bus3_info));
return 0;
}
int __init omap_register_i2c_bus(int bus_id, u32 clkrate, struct i2c_board_info const *info,  unsigned len)
{
err = i2c_register_board_info(bus_id, info, len); //把i2c设备信息记录。
omap_i2c_add_bus(bus_id);// 添加i2c 总线:作为 platform_device 添加。
}
int __init i2c_register_board_info(int busnum,  struct i2c_board_info const *info, unsigned len)
{
devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL);
list_add_tail(&devinfo->list, &__i2c_board_list);
}
//****************0: 注册 i2c 总线platform_device 的资源 与注册 ****************************************//
subsys_initcall(omap_register_i2c_bus_cmdline);
输入参数,设置总线的频率。
1:
resource: io mem and irq:
#define I2C_RESOURCE_BUILDER(base, irq)  \
{  \
.start  = (base), \
.end  = (base) + OMAP_I2C_SIZE, \
.flags  = IORESOURCE_MEM, \
},  \
{  \
.start  = (irq), \
.flags  = IORESOURCE_IRQ, \
},

static struct resource i2c_resources[][2] = {
{ I2C_RESOURCE_BUILDER(0, 0) },
#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
{ I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE2, INT_24XX_I2C2_IRQ) },
#endif
#if defined(CONFIG_ARCH_OMAP34XX)
{ I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE3, INT_34XX_I2C3_IRQ) },
#endif
};

2:
rate,时钟频率
static u32 i2c_rate[ARRAY_SIZE(i2c_resources)];
/**
 * omap_i2c_bus_setup - Process command line options for the I2C bus speed
 * @str
 * Format: i2c_bus=bus_id,clkrate (in kHz)
*/
static int __init omap_i2c_bus_setup(char *str)
{
int ports;
int ints[3];

//@@ get port number
ports = omap_i2c_nr_ports();
get_options(str, 3, ints);
if (ints[0] < 2 || ints[1] < 1 || ints[1] > ports)
return 0;
i2c_rate[ints[1] - 1] = ints[2];
i2c_rate[ints[1] - 1] |= OMAP_I2C_CMDLINE_SETUP;

return 1;
}
__setup("i2c_bus=", omap_i2c_bus_setup);


3://   i2c:  platform_device
static const char name[] = "i2c_omap";
#define I2C_DEV_BUILDER(bus_id, res, da ta) \
{  \
.id  = (bus_id), \
.name  = name, \
.num_resources = ARRAY_SIZE(res), \
.resource = (res), \
.dev  = { \
.platform_da ta = (da ta), \
},  \
}

static struct platform_device omap_i2c_devices[] = {  //***********各总线的 资源*************//
I2C_DEV_BUILDER(1, i2c_resources[0], &i2c_rate[0]),
#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
I2C_DEV_BUILDER(2, i2c_resources[1], &i2c_rate[1]),
#endif
#if defined(CONFIG_ARCH_OMAP34XX)
I2C_DEV_BUILDER(3, i2c_resources[2], &i2c_rate[2]),
#endif
};

4:  "总线设备的注册:"
static int __init omap_i2c_add_bus(int bus_id)
{
struct platform_device *pdev;
struct resource *res;
resource_size_t base, irq;

pdev = &omap_i2c_devices[bus_id - 1];
if (bus_id == 1) {   //*********注,这里把第一个i2c总线的资源重新设置了, 不是原来的 0, 0********
res = pdev->resource;
if (cpu_class_is_omap1()) {
base = OMAP1_I2C_BASE;
irq = INT_I2C;
} else {
base = OMAP2_I2C_BASE1;
irq = INT_24XX_I2C1_IRQ;
}
res[0].start = base;
res[0].end = base + OMAP_I2C_SIZE;
res[1].start = irq;
}

omap_i2c_mux_pins(bus_id - 1); //******打开 对应的  sda, scl 线。。/* Sets the Omap MUX and PULL_DWN registers based on the table
return platform_device_register(pdev);//向内核注册  i2c platform device.
}
5:引脚信息:
//@@ three i2c bus pins
static const int omap34xx_pins[][2] = {
{ K21_34XX_I2C1_SCL, J21_34XX_I2C1_SDA},
{ AF15_34XX_I2C2_SCL, AE15_34XX_I2C2_SDA},
{ AF14_34XX_I2C3_SCL, AG14_34XX_I2C3_SDA},
};

static void __init omap_i2c_mux_pins(int bus)
{
int scl, sda;

} else if (cpu_is_omap34xx()) {
scl = omap34xx_pins[bus][0];
sda = omap34xx_pins[bus][1];

omap_cfg_reg(sda);
omap_cfg_reg(scl);
}

int __init_or_module omap_cfg_reg(const unsigned long index)
{
struct omap_mux_cfg *mux_cfg;
list_for_each_entry(mux_cfg, &config_list, list)
if (mux_cfg->cfg_reg && mux_cfg->legacy) {
struct pin_config *reg = &mux_cfg->pins[index];  
//reg = MUX_CFG_34XX("K21_34XX_I2C1_SCL", 0x1ba,OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
return mux_cfg->cfg_reg(reg); // mux_cfg->cfg_reg = omap34xx_cfg_reg;
}
}
6:/*写入register: 改写OMAP的寄存器,控制引脚。*/
static int __init_or_module omap34xx_cfg_reg(const struct pin_config *cfg)
{
static DEFINE_SPINLOCK(mux_spin_lock);
unsigned long flags;
u16 reg = 0;

spin_lock_irqsave(&mux_spin_lock, flags);
reg |= cfg->mux_val;
omap2_cfg_debug(cfg, reg);
omap_ctrl_writew(reg, cfg->mux_reg);//改写寄存器 ==> __raw_writew(val, OMAP_CTRL_REGADDR(offset));
spin_unlock_irqrestore(&mux_spin_lock, flags);

return 0;
}
static void __iomem *omap2_ctrl_base;
omap2_ctrl_base = omap2_globals->ctrl;
#define OMAP_CTRL_REGADDR(reg) (omap2_ctrl_base + (reg))
#define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v))


/* IO bases for various OMAP processors */
# define __iomem __attribute__((noderef, address_space(2)))
struct omap_globals {
u32  class; /* OMAP class to detect */
void __iomem *tap; /* Control module ID co de */
void __iomem *sdrc; /* SDRAM Controller */
void __iomem *sms; /* SDRAM Memory Scheduler */
void __iomem *ctrl; /* System Control Module */
void __iomem *prm; /* Power and Reset Management */
void __iomem *cm; /* Clock Management */
};
// omap's pin_config
struct pin_config {
char  *name;
const unsigned int  mux_reg;
unsigned char debug;

#if defined(CONFIG_ARCH_OMAP34XX)
u16  mux_val; /* Wake-up, off mode, pull, mux mode */
#endif

#if defined(CONFIG_ARCH_OMAP1) || defined(CONFIG_ARCH_OMAP24XX)
const unsigned char mask_offset;
const unsigned char mask;

const char *pull_name;
const unsigned int pull_reg;
const unsigned char pull_val;
const unsigned char pull_bit;

const char *pu_pd_name;
const unsigned int pu_pd_reg;
const unsigned char pu_pd_val;
#endif

#if defined(CONFIG_OMAP_MUX_DEBUG) || defined(CONFIG_OMAP_MUX_WARNINGS)
const char *mux_reg_name;
#endif

};

//***********************1 注册 i2c总线设备的 driver  adapter ****************************************//
subsys_initcall(omap_i2c_init_driver);
static int __init omap_i2c_init_driver(void)
return platform_driver_register(&omap_i2c_driver);
static int __init omap_i2c_probe(struct platform_device *pdev)
{
struct omap_i2c_dev *dev;
dev = kzalloc(sizeof(struct omap_i2c_dev), GFP_KERNEL);
dev->dev = &pdev->dev;
platform_set_drvdata(pdev, dev);

struct i2c_adapter *adap;
adap = &dev->adapter;
adap->algo = &omap_i2c_algo;
adap->dev.parent = &pdev->dev;
r = i2c_add_numbered_adapter(adap);
}

//*************************2 注册i2c总线上的从设备驱动  i2c_driver*************************************//
static int __init twl4030_init(void)
return i2c_add_driver(&twl4030_driver);   ==> "driver->driver.bus = &i2c_bus_type;"
//************************方式 1 **进入probe后 生成所有的子从设备,绑到 i2c adapter  ***************//
因为:
struct bus_type i2c_bus_type = {
.name  = "i2c",
.dev_attrs = i2c_dev_attrs,
.match  = i2c_device_match,
.uevent  = i2c_device_uevent,
.probe  = i2c_device_probe,
.remove  = i2c_device_remove,
.shutdown = i2c_device_shutdown,
.suspend  = i2c_device_suspend,
.resume  = i2c_device_resume,
};
static int i2c_device_probe(struct device *dev) //???????????????这里第一个 i2c_bus( adapter?) 上的 i2c_client 是那里注册进去的?????
{
struct i2c_client *client = to_i2c_client(dev);
struct i2c_driver *driver = to_i2c_driver(dev->driver);
client->driver = driver;
status = driver->probe(client, i2c_match_id(driver->id_table, client));
}
//所以:  生成其所有子从设备。。。。i2c_client 及 platform_device
static int twl4030_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
for (i = 0; i < TWL4030_NUM_SLAVES; i++) {
if (i == 0)
twl->client = client;
else 
twl->client = i2c_new_dummy(client->adapter, twl->address);"创建所有子设备的 i2c_client ???"
mutex_init(&twl->xfer_lock);
}
status = add_children(pdata, id->driver_da ta);=> "根据i2c bus的 platform_device 给出的 platform_da ta, 创建所有子设备的 platform_device"
}

struct i2c_client *i2c_new_dummy(struct i2c_adapter *adapter, u16 address)
{
return i2c_new_device(adapter, &info); //
}
struct i2c_client *i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)
{
/* a new style driver may be bound to this device when we
* return from this function, or any later moment (e.g. maybe
* hotplugging will load the driver module).  and the device
* refcount model is the standard driver model on e.
*/
status = i2c_attach_client(client); ===> "adapter->client_register(client)"
}

///*****************************方式2**********************//
static inline int i2c_add_driver(struct i2c_driver *driver)
{
return i2c_register_driver(THIS_MODULE, driver);
}
 /*There
 * are two models for binding the driver to its device:  "new style" drivers
 * follow the standard Linux driver model and just respond to probe() calls
 * issued if the driver core sees they match(); "legacy" drivers create device
 * nodes themselves.
 */
int i2c_register_driver(struct module *owner, struct i2c_driver *driver)  "两种与设备绑定的方式 "
{
driver->driver.owner = owner;
driver->driver.bus = &i2c_bus_type;
/* for new style drivers, when registration returns the driver core
* will have called probe() for all matching-but-unbound devices.
*/
res = driver_register(&driver->driver);

/* Walk the adapters that are already present */
class_for_each_device(&i2c_adapter_class, NULL, driver,
     __attach_adapter);
}
static int __attach_adapter(struct device *dev, void *da ta)
{
struct i2c_adapter *adapter = to_i2c_adapter(dev);
struct i2c_driver *driver = da ta;
i2c_detect(adapter, driver);
/* Legacy drivers scan i2c busses directly */
if (driver->attach_adapter)
driver->attach_adapter(adapter);
}
static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
{
err = i2c_detect_address(temp_client, -1, driver);
}

/* Separate detection function for new-style drivers */
static int i2c_detect_address(struct i2c_client *temp_client, int kind, struct i2c_driver *driver)
{
/* Finally call the custom detection function */
err = driver->detect(temp_client, kind, &info);
}
//

//*********************所有引脚的定义。。。实现为 enum *******************************//

struct omap_mux_cfg { //????????????????????
struct list_head list;
struct pin_config *pins;
unsigned long size;
unsigned int legacy;
int  (*cfg_reg)(const struct pin_config *cfg);
};

enum omap34xx_index {
/* 34xx I2C */
K21_34XX_I2C1_SCL,
J21_34XX_I2C1_SDA,
AF15_34XX_I2C2_SCL,
AE15_34XX_I2C2_SDA,
AF14_34XX_I2C3_SCL,
AG14_34XX_I2C3_SDA,
AD26_34XX_I2C4_SCL,
AE26_34XX_I2C4_SDA,

/* PHY - HSUSB: 12-pin ULPI PHY: Port 1*/
Y8_3430_USB1HS_PHY_CLK,
Y9_3430_USB1HS_PHY_STP,
AA14_3430_USB1HS_PHY_DIR,
AA11_3430_USB1HS_PHY_NXT,
W13_3430_USB1HS_PHY_DA TA0,
W12_3430_USB1HS_PHY_DA TA1,
W11_3430_USB1HS_PHY_DA TA2,
Y11_3430_USB1HS_PHY_DA TA3,
W9_3430_USB1HS_PHY_DA TA4,
Y12_3430_USB1HS_PHY_DA TA5,
W8_3430_USB1HS_PHY_DA TA6,
Y13_3430_USB1HS_PHY_DA TA7,

/* PHY - HSUSB: 12-pin ULPI PHY: Port 2*/
AA8_3430_USB2HS_PHY_CLK,
AA10_3430_USB2HS_PHY_STP,
AA9_3430_USB2HS_PHY_DIR,
AB11_3430_USB2HS_PHY_NXT,
AB10_3430_USB2HS_PHY_DA TA0,
AB9_3430_USB2HS_PHY_DA TA1,
W3_3430_USB2HS_PHY_DA TA2,
T4_3430_USB2HS_PHY_DA TA3,
T3_3430_USB2HS_PHY_DA TA4,
R3_3430_USB2HS_PHY_DA TA5,
R4_3430_USB2HS_PHY_DA TA6,
T2_3430_USB2HS_PHY_DA TA7,


/* TLL - HSUSB: 12-pin TLL Port 1*/
Y8_3430_USB1HS_TLL_CLK,
Y9_3430_USB1HS_TLL_STP,
AA14_3430_USB1HS_TLL_DIR,
AA11_3430_USB1HS_TLL_NXT,
W13_3430_USB1HS_TLL_DA TA0,
W12_3430_USB1HS_TLL_DA TA1,
W11_3430_USB1HS_TLL_DA TA2,
Y11_3430_USB1HS_TLL_DA TA3,
W9_3430_USB1HS_TLL_DA TA4,
Y12_3430_USB1HS_TLL_DA TA5,
W8_3430_USB1HS_TLL_DA TA6,
Y13_3430_USB1HS_TLL_DA TA7,

/* TLL - HSUSB: 12-pin TLL Port 2*/
AA8_3430_USB2HS_TLL_CLK,
AA10_3430_USB2HS_TLL_STP,
AA9_3430_USB2HS_TLL_DIR,
AB11_3430_USB2HS_TLL_NXT,
AB10_3430_USB2HS_TLL_DA TA0,
AB9_3430_USB2HS_TLL_DA TA1,
W3_3430_USB2HS_TLL_DA TA2,
T4_3430_USB2HS_TLL_DA TA3,
T3_3430_USB2HS_TLL_DA TA4,
R3_3430_USB2HS_TLL_DA TA5,
R4_3430_USB2HS_TLL_DA TA6,
T2_3430_USB2HS_TLL_DA TA7,

/* TLL - HSUSB: 12-pin TLL Port 3*/
AA6_3430_USB3HS_TLL_CLK,
AB3_3430_USB3HS_TLL_STP,
AA3_3430_USB3HS_TLL_DIR,
Y3_3430_USB3HS_TLL_NXT,
AA5_3430_USB3HS_TLL_DA TA0,
Y4_3430_USB3HS_TLL_DA TA1,
Y5_3430_USB3HS_TLL_DA TA2,
W5_3430_USB3HS_TLL_DA TA3,
AB12_3430_USB3HS_TLL_DA TA4,
AB13_3430_USB3HS_TLL_DA TA5,
AA13_3430_USB3HS_TLL_DA TA6,
AA12_3430_USB3HS_TLL_DA TA7,

/* PHY FSUSB: FS Serial for Port 1 (multiple PHY modes supported) */
AF10_3430_USB1FS_PHY_MM1_RXDP,
AG9_3430_USB1FS_PHY_MM1_RXDM,
W13_3430_USB1FS_PHY_MM1_RXRCV,
W12_3430_USB1FS_PHY_MM1_TXSE0,
W11_3430_USB1FS_PHY_MM1_TXDAT,
Y11_3430_USB1FS_PHY_MM1_TXEN_N,

/* PHY FSUSB: FS Serial for Port 2 (multiple PHY modes supported) */
AF7_3430_USB2FS_PHY_MM2_RXDP,
AH7_3430_USB2FS_PHY_MM2_RXDM,
AB10_3430_USB2FS_PHY_MM2_RXRCV,
AB9_3430_USB2FS_PHY_MM2_TXSE0,
W3_3430_USB2FS_PHY_MM2_TXDAT,
T4_3430_USB2FS_PHY_MM2_TXEN_N,

/* PHY FSUSB: FS Serial for Port 3 (multiple PHY modes supported) */
AH3_3430_USB3FS_PHY_MM3_RXDP,
AE3_3430_USB3FS_PHY_MM3_RXDM,
AD1_3430_USB3FS_PHY_MM3_RXRCV,
AE1_3430_USB3FS_PHY_MM3_TXSE0,
AD2_3430_USB3FS_PHY_MM3_TXDAT,
AC1_3430_USB3FS_PHY_MM3_TXEN_N,

/* 34xx GPIO
*  - normally these are bidirectional, no internal pullup/pulldown
*  - "_UP" suffix (GPIO3_UP) if internal pullup is configured
*  - "_DOWN" suffix (GPIO3_DOWN) with internal pulldown
*  - "_OUT" suffix (GPIO3_OUT) for output-on ly pins (unlike 24xx)
*/
AF26_34XX_GPIO0,
AF21_34XX_GPIO8,
AF22_34XX_GPIO9,
AG25_34XX_GPIO10,
AB10_34XX_GPIO28_OUT,
AH8_34XX_GPIO29,
N4_34XX_GPIO34,
M4_34XX_GPIO35,
L4_34XX_GPIO36,
K4_34XX_GPIO37,
T3_34XX_GPIO38,
R3_34XX_GPIO39,
N3_34XX_GPIO40,
M3_34XX_GPIO41,
K3_34XX_GPIO43_OUT,
V8_34XX_GPIO53_OUT,
U8_34XX_GPIO54_OUT,
U8_34XX_GPIO54_DOWN,
T8_34XX_GPIO55,
T8_34XX_GPIO55_OUT,
R8_34XX_GPIO56_OUT,
P8_34XX_GPIO57_OUT,
N8_34XX_GPIO58_OUT,
T4_34XX_GPIO59_DOWN,
L8_34XX_GPIO63,
L8_34XX_GPIO63_OUT,
J8_3430_GPIO65,
G25_34XX_GPIO86_OUT,
AC27_34XX_GPIO92,
A24_34XX_GPIO94,
C25_34XX_GPIO96,
AG17_34XX_GPIO99,
AH17_34XX_GPIO100,
B24_34XX_GPIO101,
B24_34XX_GPIO101_OUT,
B25_34XX_GPIO109,
B26_34XX_GPIO111,
AG4_34XX_GPIO134_OUT,
AE4_34XX_GPIO136_OUT,
AH3_34XX_GPIO137_OUT,
AF3_34XX_GPIO138_OUT,
AE3_34XX_GPIO139_DOWN,
AF6_34XX_GPIO140_UP,
AE6_34XX_GPIO141_DOWN,
AF5_34XX_GPIO142,
AE5_34XX_GPIO143,
AA21_34XX_GPIO157_OUT,
W21_34XX_GPIO162,
H18_34XX_GPIO163,
H19_34XX_GPIO164_OUT,
B23_34XX_GPIO167,
J25_34XX_GPIO170,
AC3_34XX_GPIO175,
AB1_34XX_GPIO176_OUT,
AB2_34XX_GPIO177,
W7_34XX_GPIO178_DOWN,
T3_34XX_GPIO_179,
Y3_34XX_GPIO180,
Y4_34XX_GPIO181,
AE22_34XX_GPIO186,
AE22_34XX_GPIO186_OUT,

/* MMC1 */
N28_3430_MMC1_CLK,
M27_3430_MMC1_CMD,
N27_3430_MMC1_DAT0,
N26_3430_MMC1_DAT1,
N25_3430_MMC1_DAT2,
P28_3430_MMC1_DAT3,
P27_3430_MMC1_DAT4,
P26_3430_MMC1_DAT5,
R27_3430_MMC1_DAT6,
R25_3430_MMC1_DAT7,

/* MMC2 */
AE2_3430_MMC2_CLK,
AG5_3430_MMC2_CMD,
AH5_3430_MMC2_DAT0,
AH4_3430_MMC2_DAT1,
AG4_3430_MMC2_DAT2,
AF4_3430_MMC2_DAT3,

/* MMC3 */
AF10_3430_MMC3_CLK,
AC3_3430_MMC3_CMD,
AE11_3430_MMC3_DAT0,
AH9_3430_MMC3_DAT1,
AF13_3430_MMC3_DAT2,
AE13_3430_MMC3_DAT3,

/* UART1 */
AA8_3430_UART1_TX,
Y8_3430_UART1_RX,
AA9_3430_UART1_RTS,
W8_3430_UART1_CTS,

/* McSPI */
AB1_34XX_McSPI1_CS2,

/* DSI */
AG22_34XX_DSI_DX0,
AH22_34XX_DSI_DY0,
AG23_34XX_DSI_DX1,
AH23_34XX_DSI_DY1,
AG24_34XX_DSI_DX2,
AH24_34XX_DSI_DY2,

H16_34XX_SDRC_CKE0,
H17_34XX_SDRC_CKE1,

/* UART2 */
AA25_34XX_UART2_TX,
AD25_34XX_UART2_RX,
AB25_34XX_UART2_RTS,
AB26_34XX_UART2_CTS,

/* McBSP */
P21_OMAP34XX_MCBSP2_FSX,
N21_OMAP34XX_MCBSP2_CLKX,
R21_OMAP34XX_MCBSP2_DR,
M21_OMAP34XX_MCBSP2_DX,
K26_OMAP34XX_MCBSP3_FSX,
W21_OMAP34XX_MCBSP3_CLKX,
U21_OMAP34XX_MCBSP3_DR,
V21_OMAP34XX_MCBSP3_DX,

/* HDQ */
J25_34XX_HDQ_SIO,

/* Camera */
A24_34XX_CAM_HS,
A23_34XX_CAM_VS,
C25_34XX_CAM_XCLKA,
C27_34XX_CAM_PCLK,
C23_34XX_CAM_FLD,
AG17_34XX_CAM_D0,
AH17_34XX_CAM_D1,
B24_34XX_CAM_D2,
C24_34XX_CAM_D3,
D24_34XX_CAM_D4,
A25_34XX_CAM_D5,
K28_34XX_CAM_D6,
L28_34XX_CAM_D7,
K27_34XX_CAM_D8,
L27_34XX_CAM_D9,
B25_34XX_CAM_D10,
C26_34XX_CAM_D11,
B26_34XX_CAM_XCLKB,
B23_34XX_CAM_WEN,
D25_34XX_CAM_STROBE,
K8_34XX_GPMC_WAIT2,

/* SYS_NIRQ T2 INT1 */
AF26_34XX_SYS_NIRQ,
};
//*******************pin_config *******************************//
#define MUX_CFG_34XX(desc, reg_offset, mux_value) { \
.name  = desc, \
.debug  = 0, \
.mux_reg  = reg_offset, \
.mux_val  = mux_value \
},

Mux.c
#ifdef CONFIG_ARCH_OMAP34XX
//@@ all the pins define here
static struct pin_config __initdata_or_module omap34xx_pins[] = {
/*
 * Name, reg-offset,
 * mux-mode | [active-mode | off-mode]
 */

/* 34xx I2C */
MUX_CFG_34XX("K21_34XX_I2C1_SCL", 0x1ba,
OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
MUX_CFG_34XX("J21_34XX_I2C1_SDA", 0x1bc,
OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
MUX_CFG_34XX("AF15_34XX_I2C2_SCL", 0x1be,
OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
MUX_CFG_34XX("AE15_34XX_I2C2_SDA", 0x1c0,
OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
MUX_CFG_34XX("AF14_34XX_I2C3_SCL", 0x1c2,
OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
MUX_CFG_34XX("AG14_34XX_I2C3_SDA", 0x1c4,
OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
MUX_CFG_34XX("AD26_34XX_I2C4_SCL", 0xa00,
OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
MUX_CFG_34XX("AE26_34XX_I2C4_SDA", 0xa02,
OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)

/* PHY - HSUSB: 12-pin ULPI PHY: Port 1*/
MUX_CFG_34XX("Y8_3430_USB1HS_PHY_CLK", 0x5da,
OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT)
MUX_CFG_34XX("Y9_3430_USB1HS_PHY_STP", 0x5d8,
OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT)
MUX_CFG_34XX("AA14_3430_USB1HS_PHY_DIR", 0x5ec,
OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
MUX_CFG_34XX("AA11_3430_USB1HS_PHY_NXT", 0x5ee,
OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
MUX_CFG_34XX("W13_3430_USB1HS_PHY_D0", 0x5dc,
OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
MUX_CFG_34XX("W12_3430_USB1HS_PHY_D1", 0x5de,
OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
MUX_CFG_34XX("W11_3430_USB1HS_PHY_D2", 0x5e0,
OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
MUX_CFG_34XX("Y11_3430_USB1HS_PHY_D3", 0x5ea,
OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
MUX_CFG_34XX("W9_3430_USB1HS_PHY_D4", 0x5e4,
OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
MUX_CFG_34XX("Y12_3430_USB1HS_PHY_D5", 0x5e6,
OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
MUX_CFG_34XX("W8_3430_USB1HS_PHY_D6", 0x5e8,
OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
MUX_CFG_34XX("Y13_3430_USB1HS_PHY_D7", 0x5e2,
OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)

/* PHY - HSUSB: 12-pin ULPI PHY: Port 2*/
...
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值