1. 程式人生 > >I2C匯流排設備註冊過程

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_data = dev. pdev->dev->driver_data = 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_data 添加了其所有 子裝置的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_data = &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) }, #ifdefined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE2, INT_24XX_I2C2_IRQ) }, #endif #ifdefined(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, data)\ {  \ .id  = (bus_id),\ .name  = name,\ .num_resources= ARRAY_SIZE(res),\ .resource= (res),\ .dev  = {\ .platform_data= (data),\ },  \ } static struct platform_device omap_i2c_devices[] = {  //***********各匯流排的 資源*************// I2C_DEV_BUILDER(1, i2c_resources[0], &i2c_rate[0]), #ifdefined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) I2C_DEV_BUILDER(2, i2c_resources[1], &i2c_rate[1]), #endif #ifdefined(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 code */ 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 chardebug; #ifdefined(CONFIG_ARCH_OMAP34XX) u16  mux_val; /* Wake-up, off mode, pull, mux mode */ #endif #ifdefined(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 #ifdefined(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_data);=> "根據i2c bus的 platform_device 給出的 platform_data, 建立所有子裝置的 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 one. */ 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 *data) { struct i2c_adapter *adapter = to_i2c_adapter(dev); struct i2c_driver *driver = data; 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_headlist; struct pin_config*pins; unsigned longsize; unsigned intlegacy; 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_DATA0, W12_3430_USB1HS_PHY_DATA1, W11_3430_USB1HS_PHY_DATA2, Y11_3430_USB1HS_PHY_DATA3, W9_3430_USB1HS_PHY_DATA4, Y12_3430_USB1HS_PHY_DATA5, W8_3430_USB1HS_PHY_DATA6, Y13_3430_USB1HS_PHY_DATA7, /* 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_DATA0, AB9_3430_USB2HS_PHY_DATA1, W3_3430_USB2HS_PHY_DATA2, T4_3430_USB2HS_PHY_DATA3, T3_3430_USB2HS_PHY_DATA4, R3_3430_USB2HS_PHY_DATA5, R4_3430_USB2HS_PHY_DATA6, T2_3430_USB2HS_PHY_DATA7, /* 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_DATA0, W12_3430_USB1HS_TLL_DATA1, W11_3430_USB1HS_TLL_DATA2, Y11_3430_USB1HS_TLL_DATA3, W9_3430_USB1HS_TLL_DATA4, Y12_3430_USB1HS_TLL_DATA5, W8_3430_USB1HS_TLL_DATA6, Y13_3430_USB1HS_TLL_DATA7, /* 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_DATA0, AB9_3430_USB2HS_TLL_DATA1, W3_3430_USB2HS_TLL_DATA2, T4_3430_USB2HS_TLL_DATA3, T3_3430_USB2HS_TLL_DATA4, R3_3430_USB2HS_TLL_DATA5, R4_3430_USB2HS_TLL_DATA6, T2_3430_USB2HS_TLL_DATA7, /* 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_DATA0, Y4_3430_USB3HS_TLL_DATA1, Y5_3430_USB3HS_TLL_DATA2, W5_3430_USB3HS_TLL_DATA3, AB12_3430_USB3HS_TLL_DATA4, AB13_3430_USB3HS_TLL_DATA5, AA13_3430_USB3HS_TLL_DATA6, AA12_3430_USB3HS_TLL_DATA7, /* 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-only 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*/ ... }