diff options
| author | Jochen Friedrich <jochen@scram.de> | 2011-11-27 16:00:54 -0500 |
|---|---|---|
| committer | Samuel Ortiz <sameo@linux.intel.com> | 2012-01-08 18:37:33 -0500 |
| commit | 5dd7bf59e0e8563265b3e5b33276099ef628fcc7 (patch) | |
| tree | 1372dd626865e4ed21cac103a706f06ef6ff700e | |
| parent | c9531227b289947950cce29cfe881b768bf9d7d9 (diff) | |
ARM: sa11x0: Implement autoloading of codec and codec pdata for mcp bus.
Signed-off-by: Jochen Friedrich <jochen@scram.de>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
| -rw-r--r-- | arch/arm/mach-sa1100/assabet.c | 1 | ||||
| -rw-r--r-- | arch/arm/mach-sa1100/cerf.c | 1 | ||||
| -rw-r--r-- | arch/arm/mach-sa1100/collie.c | 8 | ||||
| -rw-r--r-- | arch/arm/mach-sa1100/include/mach/mcp.h | 2 | ||||
| -rw-r--r-- | arch/arm/mach-sa1100/lart.c | 1 | ||||
| -rw-r--r-- | arch/arm/mach-sa1100/shannon.c | 1 | ||||
| -rw-r--r-- | arch/arm/mach-sa1100/simpad.c | 8 | ||||
| -rw-r--r-- | drivers/mfd/mcp-core.c | 44 | ||||
| -rw-r--r-- | drivers/mfd/mcp-sa11x0.c | 7 | ||||
| -rw-r--r-- | drivers/mfd/ucb1x00-core.c | 48 | ||||
| -rw-r--r-- | drivers/mfd/ucb1x00-ts.c | 2 | ||||
| -rw-r--r-- | include/linux/mfd/mcp.h | 7 | ||||
| -rw-r--r-- | include/linux/mfd/ucb1x00.h | 5 | ||||
| -rw-r--r-- | include/linux/mod_devicetable.h | 11 | ||||
| -rw-r--r-- | scripts/mod/file2alias.c | 13 |
15 files changed, 138 insertions, 21 deletions
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c index 3dd133f18415..14b31f116ef9 100644 --- a/arch/arm/mach-sa1100/assabet.c +++ b/arch/arm/mach-sa1100/assabet.c | |||
| @@ -202,6 +202,7 @@ static struct irda_platform_data assabet_irda_data = { | |||
| 202 | static struct mcp_plat_data assabet_mcp_data = { | 202 | static struct mcp_plat_data assabet_mcp_data = { |
| 203 | .mccr0 = MCCR0_ADM, | 203 | .mccr0 = MCCR0_ADM, |
| 204 | .sclk_rate = 11981000, | 204 | .sclk_rate = 11981000, |
| 205 | .codec = "ucb1x00", | ||
| 205 | }; | 206 | }; |
| 206 | 207 | ||
| 207 | static void __init assabet_init(void) | 208 | static void __init assabet_init(void) |
diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c index 7f3da4b11ec9..b7db7cd08305 100644 --- a/arch/arm/mach-sa1100/cerf.c +++ b/arch/arm/mach-sa1100/cerf.c | |||
| @@ -124,6 +124,7 @@ static void __init cerf_map_io(void) | |||
| 124 | static struct mcp_plat_data cerf_mcp_data = { | 124 | static struct mcp_plat_data cerf_mcp_data = { |
| 125 | .mccr0 = MCCR0_ADM, | 125 | .mccr0 = MCCR0_ADM, |
| 126 | .sclk_rate = 11981000, | 126 | .sclk_rate = 11981000, |
| 127 | .codec = "ucb1x00", | ||
| 127 | }; | 128 | }; |
| 128 | 129 | ||
| 129 | static void __init cerf_init(void) | 130 | static void __init cerf_init(void) |
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c index 2965cc9d424e..b0b5efee683b 100644 --- a/arch/arm/mach-sa1100/collie.c +++ b/arch/arm/mach-sa1100/collie.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <linux/timer.h> | 27 | #include <linux/timer.h> |
| 28 | #include <linux/gpio.h> | 28 | #include <linux/gpio.h> |
| 29 | #include <linux/pda_power.h> | 29 | #include <linux/pda_power.h> |
| 30 | #include <linux/mfd/ucb1x00.h> | ||
| 30 | 31 | ||
| 31 | #include <mach/hardware.h> | 32 | #include <mach/hardware.h> |
| 32 | #include <asm/mach-types.h> | 33 | #include <asm/mach-types.h> |
| @@ -85,10 +86,15 @@ static struct scoop_pcmcia_config collie_pcmcia_config = { | |||
| 85 | .num_devs = 1, | 86 | .num_devs = 1, |
| 86 | }; | 87 | }; |
| 87 | 88 | ||
| 89 | static struct ucb1x00_plat_data collie_ucb1x00_data = { | ||
| 90 | .gpio_base = COLLIE_TC35143_GPIO_BASE, | ||
| 91 | }; | ||
| 92 | |||
| 88 | static struct mcp_plat_data collie_mcp_data = { | 93 | static struct mcp_plat_data collie_mcp_data = { |
| 89 | .mccr0 = MCCR0_ADM | MCCR0_ExtClk, | 94 | .mccr0 = MCCR0_ADM | MCCR0_ExtClk, |
| 90 | .sclk_rate = 9216000, | 95 | .sclk_rate = 9216000, |
| 91 | .gpio_base = COLLIE_TC35143_GPIO_BASE, | 96 | .codec = "ucb1x00", |
| 97 | .codec_pdata = &collie_ucb1x00_data, | ||
| 92 | }; | 98 | }; |
| 93 | 99 | ||
| 94 | /* | 100 | /* |
diff --git a/arch/arm/mach-sa1100/include/mach/mcp.h b/arch/arm/mach-sa1100/include/mach/mcp.h index ed1a331508a7..586cec898b35 100644 --- a/arch/arm/mach-sa1100/include/mach/mcp.h +++ b/arch/arm/mach-sa1100/include/mach/mcp.h | |||
| @@ -17,6 +17,8 @@ struct mcp_plat_data { | |||
| 17 | u32 mccr1; | 17 | u32 mccr1; |
| 18 | unsigned int sclk_rate; | 18 | unsigned int sclk_rate; |
| 19 | int gpio_base; | 19 | int gpio_base; |
| 20 | const char *codec; | ||
| 21 | void *codec_pdata; | ||
| 20 | }; | 22 | }; |
| 21 | 23 | ||
| 22 | #endif | 24 | #endif |
diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c index 5bc59d0947ba..34bbdd986e43 100644 --- a/arch/arm/mach-sa1100/lart.c +++ b/arch/arm/mach-sa1100/lart.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | static struct mcp_plat_data lart_mcp_data = { | 24 | static struct mcp_plat_data lart_mcp_data = { |
| 25 | .mccr0 = MCCR0_ADM, | 25 | .mccr0 = MCCR0_ADM, |
| 26 | .sclk_rate = 11981000, | 26 | .sclk_rate = 11981000, |
| 27 | .codec = "ucb1x00", | ||
| 27 | }; | 28 | }; |
| 28 | 29 | ||
| 29 | static void __init lart_init(void) | 30 | static void __init lart_init(void) |
diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c index 1cccbf5b9e9a..252faa5e2395 100644 --- a/arch/arm/mach-sa1100/shannon.c +++ b/arch/arm/mach-sa1100/shannon.c | |||
| @@ -55,6 +55,7 @@ static struct resource shannon_flash_resource = { | |||
| 55 | static struct mcp_plat_data shannon_mcp_data = { | 55 | static struct mcp_plat_data shannon_mcp_data = { |
| 56 | .mccr0 = MCCR0_ADM, | 56 | .mccr0 = MCCR0_ADM, |
| 57 | .sclk_rate = 11981000, | 57 | .sclk_rate = 11981000, |
| 58 | .codec = "ucb1x00", | ||
| 58 | }; | 59 | }; |
| 59 | 60 | ||
| 60 | static void __init shannon_init(void) | 61 | static void __init shannon_init(void) |
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c index 4790f3f3d008..7eac8ebab94e 100644 --- a/arch/arm/mach-sa1100/simpad.c +++ b/arch/arm/mach-sa1100/simpad.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/mtd/partitions.h> | 14 | #include <linux/mtd/partitions.h> |
| 15 | #include <linux/io.h> | 15 | #include <linux/io.h> |
| 16 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
| 17 | #include <linux/mfd/ucb1x00.h> | ||
| 17 | 18 | ||
| 18 | #include <asm/irq.h> | 19 | #include <asm/irq.h> |
| 19 | #include <mach/hardware.h> | 20 | #include <mach/hardware.h> |
| @@ -187,10 +188,15 @@ static struct resource simpad_flash_resources [] = { | |||
| 187 | } | 188 | } |
| 188 | }; | 189 | }; |
| 189 | 190 | ||
| 191 | static struct ucb1x00_plat_data simpad_ucb1x00_data = { | ||
| 192 | .gpio_base = SIMPAD_UCB1X00_GPIO_BASE, | ||
| 193 | }; | ||
| 194 | |||
| 190 | static struct mcp_plat_data simpad_mcp_data = { | 195 | static struct mcp_plat_data simpad_mcp_data = { |
| 191 | .mccr0 = MCCR0_ADM, | 196 | .mccr0 = MCCR0_ADM, |
| 192 | .sclk_rate = 11981000, | 197 | .sclk_rate = 11981000, |
| 193 | .gpio_base = SIMPAD_UCB1X00_GPIO_BASE, | 198 | .codec = "ucb1300", |
| 199 | .codec_pdata = &simpad_ucb1x00_data, | ||
| 194 | }; | 200 | }; |
| 195 | 201 | ||
| 196 | 202 | ||
diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c index 84815f9ef636..63be60bc3455 100644 --- a/drivers/mfd/mcp-core.c +++ b/drivers/mfd/mcp-core.c | |||
| @@ -26,9 +26,35 @@ | |||
| 26 | #define to_mcp(d) container_of(d, struct mcp, attached_device) | 26 | #define to_mcp(d) container_of(d, struct mcp, attached_device) |
| 27 | #define to_mcp_driver(d) container_of(d, struct mcp_driver, drv) | 27 | #define to_mcp_driver(d) container_of(d, struct mcp_driver, drv) |
| 28 | 28 | ||
| 29 | static const struct mcp_device_id *mcp_match_id(const struct mcp_device_id *id, | ||
| 30 | const char *codec) | ||
| 31 | { | ||
| 32 | while (id->name[0]) { | ||
| 33 | if (strcmp(codec, id->name) == 0) | ||
| 34 | return id; | ||
| 35 | id++; | ||
| 36 | } | ||
| 37 | return NULL; | ||
| 38 | } | ||
| 39 | |||
| 40 | const struct mcp_device_id *mcp_get_device_id(const struct mcp *mcp) | ||
| 41 | { | ||
| 42 | const struct mcp_driver *driver = | ||
| 43 | to_mcp_driver(mcp->attached_device.driver); | ||
| 44 | |||
| 45 | return mcp_match_id(driver->id_table, mcp->codec); | ||
| 46 | } | ||
| 47 | EXPORT_SYMBOL(mcp_get_device_id); | ||
| 48 | |||
| 29 | static int mcp_bus_match(struct device *dev, struct device_driver *drv) | 49 | static int mcp_bus_match(struct device *dev, struct device_driver *drv) |
| 30 | { | 50 | { |
| 31 | return 1; | 51 | const struct mcp *mcp = to_mcp(dev); |
| 52 | const struct mcp_driver *driver = to_mcp_driver(drv); | ||
| 53 | |||
| 54 | if (driver->id_table) | ||
| 55 | return !!mcp_match_id(driver->id_table, mcp->codec); | ||
| 56 | |||
| 57 | return 0; | ||
| 32 | } | 58 | } |
| 33 | 59 | ||
| 34 | static int mcp_bus_probe(struct device *dev) | 60 | static int mcp_bus_probe(struct device *dev) |
| @@ -74,9 +100,18 @@ static int mcp_bus_resume(struct device *dev) | |||
| 74 | return ret; | 100 | return ret; |
| 75 | } | 101 | } |
| 76 | 102 | ||
| 103 | static int mcp_bus_uevent(struct device *dev, struct kobj_uevent_env *env) | ||
| 104 | { | ||
| 105 | struct mcp *mcp = to_mcp(dev); | ||
| 106 | |||
| 107 | add_uevent_var(env, "MODALIAS=%s%s", MCP_MODULE_PREFIX, mcp->codec); | ||
| 108 | return 0; | ||
| 109 | } | ||
| 110 | |||
| 77 | static struct bus_type mcp_bus_type = { | 111 | static struct bus_type mcp_bus_type = { |
| 78 | .name = "mcp", | 112 | .name = "mcp", |
| 79 | .match = mcp_bus_match, | 113 | .match = mcp_bus_match, |
| 114 | .uevent = mcp_bus_uevent, | ||
| 80 | .probe = mcp_bus_probe, | 115 | .probe = mcp_bus_probe, |
| 81 | .remove = mcp_bus_remove, | 116 | .remove = mcp_bus_remove, |
| 82 | .suspend = mcp_bus_suspend, | 117 | .suspend = mcp_bus_suspend, |
| @@ -212,9 +247,14 @@ struct mcp *mcp_host_alloc(struct device *parent, size_t size) | |||
| 212 | } | 247 | } |
| 213 | EXPORT_SYMBOL(mcp_host_alloc); | 248 | EXPORT_SYMBOL(mcp_host_alloc); |
| 214 | 249 | ||
| 215 | int mcp_host_register(struct mcp *mcp) | 250 | int mcp_host_register(struct mcp *mcp, void *pdata) |
| 216 | { | 251 | { |
| 252 | if (!mcp->codec) | ||
| 253 | return -EINVAL; | ||
| 254 | |||
| 255 | mcp->attached_device.platform_data = pdata; | ||
| 217 | dev_set_name(&mcp->attached_device, "mcp0"); | 256 | dev_set_name(&mcp->attached_device, "mcp0"); |
| 257 | request_module("%s%s", MCP_MODULE_PREFIX, mcp->codec); | ||
| 218 | return device_register(&mcp->attached_device); | 258 | return device_register(&mcp->attached_device); |
| 219 | } | 259 | } |
| 220 | EXPORT_SYMBOL(mcp_host_register); | 260 | EXPORT_SYMBOL(mcp_host_register); |
diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c index 02c53a0766c4..da4e077a1bee 100644 --- a/drivers/mfd/mcp-sa11x0.c +++ b/drivers/mfd/mcp-sa11x0.c | |||
| @@ -146,6 +146,9 @@ static int mcp_sa11x0_probe(struct platform_device *pdev) | |||
| 146 | if (!data) | 146 | if (!data) |
| 147 | return -ENODEV; | 147 | return -ENODEV; |
| 148 | 148 | ||
| 149 | if (!data->codec) | ||
| 150 | return -ENODEV; | ||
| 151 | |||
| 149 | if (!request_mem_region(0x80060000, 0x60, "sa11x0-mcp")) | 152 | if (!request_mem_region(0x80060000, 0x60, "sa11x0-mcp")) |
| 150 | return -EBUSY; | 153 | return -EBUSY; |
| 151 | 154 | ||
| @@ -162,7 +165,7 @@ static int mcp_sa11x0_probe(struct platform_device *pdev) | |||
| 162 | mcp->dma_audio_wr = DMA_Ser4MCP0Wr; | 165 | mcp->dma_audio_wr = DMA_Ser4MCP0Wr; |
| 163 | mcp->dma_telco_rd = DMA_Ser4MCP1Rd; | 166 | mcp->dma_telco_rd = DMA_Ser4MCP1Rd; |
| 164 | mcp->dma_telco_wr = DMA_Ser4MCP1Wr; | 167 | mcp->dma_telco_wr = DMA_Ser4MCP1Wr; |
| 165 | mcp->gpio_base = data->gpio_base; | 168 | mcp->codec = data->codec; |
| 166 | 169 | ||
| 167 | platform_set_drvdata(pdev, mcp); | 170 | platform_set_drvdata(pdev, mcp); |
| 168 | 171 | ||
| @@ -195,7 +198,7 @@ static int mcp_sa11x0_probe(struct platform_device *pdev) | |||
| 195 | mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) / | 198 | mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) / |
| 196 | mcp->sclk_rate; | 199 | mcp->sclk_rate; |
| 197 | 200 | ||
| 198 | ret = mcp_host_register(mcp); | 201 | ret = mcp_host_register(mcp, data->codec_pdata); |
| 199 | if (ret == 0) | 202 | if (ret == 0) |
| 200 | goto out; | 203 | goto out; |
| 201 | 204 | ||
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c index b281217334eb..91c4f25e0e55 100644 --- a/drivers/mfd/ucb1x00-core.c +++ b/drivers/mfd/ucb1x00-core.c | |||
| @@ -36,6 +36,15 @@ static DEFINE_MUTEX(ucb1x00_mutex); | |||
| 36 | static LIST_HEAD(ucb1x00_drivers); | 36 | static LIST_HEAD(ucb1x00_drivers); |
| 37 | static LIST_HEAD(ucb1x00_devices); | 37 | static LIST_HEAD(ucb1x00_devices); |
| 38 | 38 | ||
| 39 | static struct mcp_device_id ucb1x00_id[] = { | ||
| 40 | { "ucb1x00", 0 }, /* auto-detection */ | ||
| 41 | { "ucb1200", UCB_ID_1200 }, | ||
| 42 | { "ucb1300", UCB_ID_1300 }, | ||
| 43 | { "tc35143", UCB_ID_TC35143 }, | ||
| 44 | { } | ||
| 45 | }; | ||
| 46 | MODULE_DEVICE_TABLE(mcp, ucb1x00_id); | ||
| 47 | |||
| 39 | /** | 48 | /** |
| 40 | * ucb1x00_io_set_dir - set IO direction | 49 | * ucb1x00_io_set_dir - set IO direction |
| 41 | * @ucb: UCB1x00 structure describing chip | 50 | * @ucb: UCB1x00 structure describing chip |
| @@ -527,17 +536,33 @@ static struct class ucb1x00_class = { | |||
| 527 | 536 | ||
| 528 | static int ucb1x00_probe(struct mcp *mcp) | 537 | static int ucb1x00_probe(struct mcp *mcp) |
| 529 | { | 538 | { |
| 539 | const struct mcp_device_id *mid; | ||
| 530 | struct ucb1x00 *ucb; | 540 | struct ucb1x00 *ucb; |
| 531 | struct ucb1x00_driver *drv; | 541 | struct ucb1x00_driver *drv; |
| 542 | struct ucb1x00_plat_data *pdata; | ||
| 532 | unsigned int id; | 543 | unsigned int id; |
| 533 | int ret = -ENODEV; | 544 | int ret = -ENODEV; |
| 534 | int temp; | 545 | int temp; |
| 535 | 546 | ||
| 536 | mcp_enable(mcp); | 547 | mcp_enable(mcp); |
| 537 | id = mcp_reg_read(mcp, UCB_ID); | 548 | id = mcp_reg_read(mcp, UCB_ID); |
| 549 | mid = mcp_get_device_id(mcp); | ||
| 538 | 550 | ||
| 539 | if (id != UCB_ID_1200 && id != UCB_ID_1300 && id != UCB_ID_TC35143) { | 551 | if (mid && mid->driver_data) { |
| 540 | printk(KERN_WARNING "UCB1x00 ID not found: %04x\n", id); | 552 | if (id != mid->driver_data) { |
| 553 | printk(KERN_WARNING "%s wrong ID %04x found: %04x\n", | ||
| 554 | mid->name, (unsigned int) mid->driver_data, id); | ||
| 555 | goto err_disable; | ||
| 556 | } | ||
| 557 | } else { | ||
| 558 | mid = &ucb1x00_id[1]; | ||
| 559 | while (mid->driver_data) { | ||
| 560 | if (id == mid->driver_data) | ||
| 561 | break; | ||
| 562 | mid++; | ||
| 563 | } | ||
| 564 | printk(KERN_WARNING "%s ID not found: %04x\n", | ||
| 565 | ucb1x00_id[0].name, id); | ||
| 541 | goto err_disable; | 566 | goto err_disable; |
| 542 | } | 567 | } |
| 543 | 568 | ||
| @@ -546,28 +571,28 @@ static int ucb1x00_probe(struct mcp *mcp) | |||
| 546 | if (!ucb) | 571 | if (!ucb) |
| 547 | goto err_disable; | 572 | goto err_disable; |
| 548 | 573 | ||
| 549 | 574 | pdata = mcp->attached_device.platform_data; | |
| 550 | ucb->dev.class = &ucb1x00_class; | 575 | ucb->dev.class = &ucb1x00_class; |
| 551 | ucb->dev.parent = &mcp->attached_device; | 576 | ucb->dev.parent = &mcp->attached_device; |
| 552 | dev_set_name(&ucb->dev, "ucb1x00"); | 577 | dev_set_name(&ucb->dev, mid->name); |
| 553 | 578 | ||
| 554 | spin_lock_init(&ucb->lock); | 579 | spin_lock_init(&ucb->lock); |
| 555 | spin_lock_init(&ucb->io_lock); | 580 | spin_lock_init(&ucb->io_lock); |
| 556 | sema_init(&ucb->adc_sem, 1); | 581 | sema_init(&ucb->adc_sem, 1); |
| 557 | 582 | ||
| 558 | ucb->id = id; | 583 | ucb->id = mid; |
| 559 | ucb->mcp = mcp; | 584 | ucb->mcp = mcp; |
| 560 | ucb->irq = ucb1x00_detect_irq(ucb); | 585 | ucb->irq = ucb1x00_detect_irq(ucb); |
| 561 | if (ucb->irq == NO_IRQ) { | 586 | if (ucb->irq == NO_IRQ) { |
| 562 | printk(KERN_ERR "UCB1x00: IRQ probe failed\n"); | 587 | printk(KERN_ERR "%s: IRQ probe failed\n", mid->name); |
| 563 | ret = -ENODEV; | 588 | ret = -ENODEV; |
| 564 | goto err_free; | 589 | goto err_free; |
| 565 | } | 590 | } |
| 566 | 591 | ||
| 567 | ucb->gpio.base = -1; | 592 | ucb->gpio.base = -1; |
| 568 | if (mcp->gpio_base != 0) { | 593 | if (pdata && (pdata->gpio_base >= 0)) { |
| 569 | ucb->gpio.label = dev_name(&ucb->dev); | 594 | ucb->gpio.label = dev_name(&ucb->dev); |
| 570 | ucb->gpio.base = mcp->gpio_base; | 595 | ucb->gpio.base = pdata->gpio_base; |
| 571 | ucb->gpio.ngpio = 10; | 596 | ucb->gpio.ngpio = 10; |
| 572 | ucb->gpio.set = ucb1x00_gpio_set; | 597 | ucb->gpio.set = ucb1x00_gpio_set; |
| 573 | ucb->gpio.get = ucb1x00_gpio_get; | 598 | ucb->gpio.get = ucb1x00_gpio_get; |
| @@ -580,10 +605,10 @@ static int ucb1x00_probe(struct mcp *mcp) | |||
| 580 | dev_info(&ucb->dev, "gpio_base not set so no gpiolib support"); | 605 | dev_info(&ucb->dev, "gpio_base not set so no gpiolib support"); |
| 581 | 606 | ||
| 582 | ret = request_irq(ucb->irq, ucb1x00_irq, IRQF_TRIGGER_RISING, | 607 | ret = request_irq(ucb->irq, ucb1x00_irq, IRQF_TRIGGER_RISING, |
| 583 | "UCB1x00", ucb); | 608 | mid->name, ucb); |
| 584 | if (ret) { | 609 | if (ret) { |
| 585 | printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n", | 610 | printk(KERN_ERR "%s: unable to grab irq%d: %d\n", |
| 586 | ucb->irq, ret); | 611 | mid->name, ucb->irq, ret); |
| 587 | goto err_gpio; | 612 | goto err_gpio; |
| 588 | } | 613 | } |
| 589 | 614 | ||
| @@ -705,6 +730,7 @@ static struct mcp_driver ucb1x00_driver = { | |||
| 705 | .remove = ucb1x00_remove, | 730 | .remove = ucb1x00_remove, |
| 706 | .suspend = ucb1x00_suspend, | 731 | .suspend = ucb1x00_suspend, |
| 707 | .resume = ucb1x00_resume, | 732 | .resume = ucb1x00_resume, |
| 733 | .id_table = ucb1x00_id, | ||
| 708 | }; | 734 | }; |
| 709 | 735 | ||
| 710 | static int __init ucb1x00_init(void) | 736 | static int __init ucb1x00_init(void) |
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c index 38ffbd50a0d2..40ec3c118868 100644 --- a/drivers/mfd/ucb1x00-ts.c +++ b/drivers/mfd/ucb1x00-ts.c | |||
| @@ -382,7 +382,7 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev) | |||
| 382 | ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC; | 382 | ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC; |
| 383 | 383 | ||
| 384 | idev->name = "Touchscreen panel"; | 384 | idev->name = "Touchscreen panel"; |
| 385 | idev->id.product = ts->ucb->id; | 385 | idev->id.product = ts->ucb->id->driver_data; |
| 386 | idev->open = ucb1x00_ts_open; | 386 | idev->open = ucb1x00_ts_open; |
| 387 | idev->close = ucb1x00_ts_close; | 387 | idev->close = ucb1x00_ts_close; |
| 388 | 388 | ||
diff --git a/include/linux/mfd/mcp.h b/include/linux/mfd/mcp.h index ee496708e38b..1515e64e3663 100644 --- a/include/linux/mfd/mcp.h +++ b/include/linux/mfd/mcp.h | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #ifndef MCP_H | 10 | #ifndef MCP_H |
| 11 | #define MCP_H | 11 | #define MCP_H |
| 12 | 12 | ||
| 13 | #include <linux/mod_devicetable.h> | ||
| 13 | #include <mach/dma.h> | 14 | #include <mach/dma.h> |
| 14 | 15 | ||
| 15 | struct mcp_ops; | 16 | struct mcp_ops; |
| @@ -26,7 +27,7 @@ struct mcp { | |||
| 26 | dma_device_t dma_telco_rd; | 27 | dma_device_t dma_telco_rd; |
| 27 | dma_device_t dma_telco_wr; | 28 | dma_device_t dma_telco_wr; |
| 28 | struct device attached_device; | 29 | struct device attached_device; |
| 29 | int gpio_base; | 30 | const char *codec; |
| 30 | }; | 31 | }; |
| 31 | 32 | ||
| 32 | struct mcp_ops { | 33 | struct mcp_ops { |
| @@ -44,10 +45,11 @@ void mcp_reg_write(struct mcp *, unsigned int, unsigned int); | |||
| 44 | unsigned int mcp_reg_read(struct mcp *, unsigned int); | 45 | unsigned int mcp_reg_read(struct mcp *, unsigned int); |
| 45 | void mcp_enable(struct mcp *); | 46 | void mcp_enable(struct mcp *); |
| 46 | void mcp_disable(struct mcp *); | 47 | void mcp_disable(struct mcp *); |
| 48 | const struct mcp_device_id *mcp_get_device_id(const struct mcp *mcp); | ||
| 47 | #define mcp_get_sclk_rate(mcp) ((mcp)->sclk_rate) | 49 | #define mcp_get_sclk_rate(mcp) ((mcp)->sclk_rate) |
| 48 | 50 | ||
| 49 | struct mcp *mcp_host_alloc(struct device *, size_t); | 51 | struct mcp *mcp_host_alloc(struct device *, size_t); |
| 50 | int mcp_host_register(struct mcp *); | 52 | int mcp_host_register(struct mcp *, void *); |
| 51 | void mcp_host_unregister(struct mcp *); | 53 | void mcp_host_unregister(struct mcp *); |
| 52 | 54 | ||
| 53 | struct mcp_driver { | 55 | struct mcp_driver { |
| @@ -56,6 +58,7 @@ struct mcp_driver { | |||
| 56 | void (*remove)(struct mcp *); | 58 | void (*remove)(struct mcp *); |
| 57 | int (*suspend)(struct mcp *, pm_message_t); | 59 | int (*suspend)(struct mcp *, pm_message_t); |
| 58 | int (*resume)(struct mcp *); | 60 | int (*resume)(struct mcp *); |
| 61 | const struct mcp_device_id *id_table; | ||
| 59 | }; | 62 | }; |
| 60 | 63 | ||
| 61 | int mcp_driver_register(struct mcp_driver *); | 64 | int mcp_driver_register(struct mcp_driver *); |
diff --git a/include/linux/mfd/ucb1x00.h b/include/linux/mfd/ucb1x00.h index 4321f044d1e4..bc19e5fb7ea8 100644 --- a/include/linux/mfd/ucb1x00.h +++ b/include/linux/mfd/ucb1x00.h | |||
| @@ -104,6 +104,9 @@ | |||
| 104 | #define UCB_MODE_DYN_VFLAG_ENA (1 << 12) | 104 | #define UCB_MODE_DYN_VFLAG_ENA (1 << 12) |
| 105 | #define UCB_MODE_AUD_OFF_CAN (1 << 13) | 105 | #define UCB_MODE_AUD_OFF_CAN (1 << 13) |
| 106 | 106 | ||
| 107 | struct ucb1x00_plat_data { | ||
| 108 | int gpio_base; | ||
| 109 | }; | ||
| 107 | 110 | ||
| 108 | struct ucb1x00_irq { | 111 | struct ucb1x00_irq { |
| 109 | void *devid; | 112 | void *devid; |
| @@ -116,7 +119,7 @@ struct ucb1x00 { | |||
| 116 | unsigned int irq; | 119 | unsigned int irq; |
| 117 | struct semaphore adc_sem; | 120 | struct semaphore adc_sem; |
| 118 | spinlock_t io_lock; | 121 | spinlock_t io_lock; |
| 119 | u16 id; | 122 | const struct mcp_device_id *id; |
| 120 | u16 io_dir; | 123 | u16 io_dir; |
| 121 | u16 io_out; | 124 | u16 io_out; |
| 122 | u16 adc_cr; | 125 | u16 adc_cr; |
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 468819cdde87..bc50d9a80d89 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h | |||
| @@ -436,6 +436,17 @@ struct spi_device_id { | |||
| 436 | __attribute__((aligned(sizeof(kernel_ulong_t)))); | 436 | __attribute__((aligned(sizeof(kernel_ulong_t)))); |
| 437 | }; | 437 | }; |
| 438 | 438 | ||
| 439 | /* mcp */ | ||
| 440 | |||
| 441 | #define MCP_NAME_SIZE 20 | ||
| 442 | #define MCP_MODULE_PREFIX "mcp:" | ||
| 443 | |||
| 444 | struct mcp_device_id { | ||
| 445 | char name[MCP_NAME_SIZE]; | ||
| 446 | kernel_ulong_t driver_data /* Data private to the driver */ | ||
| 447 | __attribute__((aligned(sizeof(kernel_ulong_t)))); | ||
| 448 | }; | ||
| 449 | |||
| 439 | /* dmi */ | 450 | /* dmi */ |
| 440 | enum dmi_field { | 451 | enum dmi_field { |
| 441 | DMI_NONE, | 452 | DMI_NONE, |
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index f936d1fa969d..e8c7eb16c0ea 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c | |||
| @@ -774,6 +774,15 @@ static int do_spi_entry(const char *filename, struct spi_device_id *id, | |||
| 774 | return 1; | 774 | return 1; |
| 775 | } | 775 | } |
| 776 | 776 | ||
| 777 | /* Looks like: mcp:S */ | ||
| 778 | static int do_mcp_entry(const char *filename, struct mcp_device_id *id, | ||
| 779 | char *alias) | ||
| 780 | { | ||
| 781 | sprintf(alias, MCP_MODULE_PREFIX "%s", id->name); | ||
| 782 | |||
| 783 | return 1; | ||
| 784 | } | ||
| 785 | |||
| 777 | static const struct dmifield { | 786 | static const struct dmifield { |
| 778 | const char *prefix; | 787 | const char *prefix; |
| 779 | int field; | 788 | int field; |
| @@ -1027,6 +1036,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, | |||
| 1027 | do_table(symval, sym->st_size, | 1036 | do_table(symval, sym->st_size, |
| 1028 | sizeof(struct spi_device_id), "spi", | 1037 | sizeof(struct spi_device_id), "spi", |
| 1029 | do_spi_entry, mod); | 1038 | do_spi_entry, mod); |
| 1039 | else if (sym_is(symname, "__mod_mcp_device_table")) | ||
| 1040 | do_table(symval, sym->st_size, | ||
| 1041 | sizeof(struct mcp_device_id), "mcp", | ||
| 1042 | do_mcp_entry, mod); | ||
| 1030 | else if (sym_is(symname, "__mod_dmi_device_table")) | 1043 | else if (sym_is(symname, "__mod_dmi_device_table")) |
| 1031 | do_table(symval, sym->st_size, | 1044 | do_table(symval, sym->st_size, |
| 1032 | sizeof(struct dmi_system_id), "dmi", | 1045 | sizeof(struct dmi_system_id), "dmi", |
