/* * (c) 2010 STMicroelectronics Limited * * Author: Pawel Moll * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include #include #include #include #include #include #include /* ASC resources ---------------------------------------------------------- */ static struct stm_pad_config stx7105_asc0_pio0_pad_config = { .gpios_num = 4, .gpios = (struct stm_pad_gpio []) { STM_PAD_PIO_OUT(0, 0, 4), /* TX */ STM_PAD_PIO_IN(0, 1, -1), /* RX */ STM_PAD_PIO_IN_NAMED(0, 4, -1, "CTS"), STM_PAD_PIO_OUT_NAMED(0, 3, 4, "RTS"), }, }; static struct stm_pad_config stx7105_asc1_pio1_pad_config = { .gpios_num = 4, .gpios = (struct stm_pad_gpio []) { STM_PAD_PIO_OUT(1, 0, 4), /* TX */ STM_PAD_PIO_IN(1, 1, -1), /* RX */ STM_PAD_PIO_IN_NAMED(1, 4, -1, "CTS"), STM_PAD_PIO_OUT_NAMED(1, 3, 4, "RTS"), }, }; static struct stm_pad_config stx7105_asc2_pio4_pad_config = { .gpios_num = 4, .gpios = (struct stm_pad_gpio []) { STM_PAD_PIO_OUT(4, 0, 3), /* TX */ STM_PAD_PIO_IN(4, 1, -1), /* RX */ STM_PAD_PIO_IN_NAMED(4, 2, -1, "CTS"), STM_PAD_PIO_OUT_NAMED(4, 3, 3, "RTS"), }, .sysconfs_num = 2, .sysconfs = (struct stm_pad_sysconf []) { /* uart2_rxd_src_select: 0 = PIO4.1, 1 = PIO12.1 */ STM_PAD_SYS_CFG(7, 1, 1, 0), /* uart2_cts_src_select: 0 = PIO4.2, 1 = PIO12.2 */ STM_PAD_SYS_CFG(7, 2, 2, 0), }, }; static struct stm_pad_config stx7106_asc2_pio12_pad_config = { .gpios_num = 4, .gpios = (struct stm_pad_gpio []) { STM_PAD_PIO_OUT(12, 0, 5), /* TX */ STM_PAD_PIO_IN(12, 1, -1), /* RX */ STM_PAD_PIO_IN_NAMED(12, 2, -1, "CTS"), STM_PAD_PIO_OUT_NAMED(12, 3, 5, "RTS"), }, .sysconfs_num = 2, .sysconfs = (struct stm_pad_sysconf []) { /* uart2_rxd_src_select: * 0 = PIO4.1, 1 = PIO12.1, 2 = PIO14.1 */ STM_PAD_SYS_CFG(7, 1, 2, 1), /* uart2_cts_src_select: * 0 = PIO4.2, 1 = PIO12.2, 2 = PIO14.2 */ STM_PAD_SYS_CFG(16, 1, 2, 1), }, }; static struct stm_pad_config stx7105_asc2_pio12_pad_config = { .gpios_num = 4, .gpios = (struct stm_pad_gpio []) { STM_PAD_PIO_OUT(12, 0, 5), /* TX */ STM_PAD_PIO_IN(12, 1, -1), /* RX */ STM_PAD_PIO_IN_NAMED(12, 2, -1, "CTS"), STM_PAD_PIO_OUT_NAMED(12, 3, 5, "RTS"), }, .sysconfs_num = 2, .sysconfs = (struct stm_pad_sysconf []) { /* uart2_rxd_src_select: 0 = PIO4.1, 1 = PIO12.1 */ STM_PAD_SYS_CFG(7, 1, 1, 1), /* uart2_cts_src_select: 0 = PIO4.2, 1 = PIO12.2 */ STM_PAD_SYS_CFG(7, 2, 2, 1), }, }; static struct stm_pad_config stx7105_asc3_pio5_pad_config = { .gpios_num = 4, .gpios = (struct stm_pad_gpio []) { STM_PAD_PIO_OUT(5, 0, 3), /* TX */ STM_PAD_PIO_IN(5, 1, -1), /* RX */ STM_PAD_PIO_IN_NAMED(5, 3, -1, "CTS"), STM_PAD_PIO_OUT_NAMED(5, 2, 3, "RTS"), }, }; static struct platform_device stx7105_asc_devices[] = { [0] = { .name = "stm-asc", /* .id set in stx7105_configure_asc() */ .num_resources = 4, .resource = (struct resource[]) { STM_PLAT_RESOURCE_MEM(0xfd030000, 0x2c), STM_PLAT_RESOURCE_IRQ(evt2irq(0x1160), -1), STM_PLAT_RESOURCE_DMA_NAMED("rx_half_full", 11), STM_PLAT_RESOURCE_DMA_NAMED("tx_half_empty", 15), }, .dev.platform_data = &(struct stm_plat_asc_data) { .pad_config = &stx7105_asc0_pio0_pad_config, }, }, [1] = { .name = "stm-asc", /* .id set in stx7105_configure_asc() */ .num_resources = 4, .resource = (struct resource[]) { STM_PLAT_RESOURCE_MEM(0xfd031000, 0x2c), STM_PLAT_RESOURCE_IRQ(evt2irq(0x1140), -1), STM_PLAT_RESOURCE_DMA_NAMED("rx_half_full", 12), STM_PLAT_RESOURCE_DMA_NAMED("tx_half_empty", 16), }, .dev.platform_data = &(struct stm_plat_asc_data) { .pad_config = &stx7105_asc1_pio1_pad_config }, }, [2] = { .name = "stm-asc", /* .id set in stx7105_configure_asc() */ .num_resources = 4, .resource = (struct resource[]) { STM_PLAT_RESOURCE_MEM(0xfd032000, 0x2c), STM_PLAT_RESOURCE_IRQ(evt2irq(0x1120), -1), STM_PLAT_RESOURCE_DMA_NAMED("rx_half_full", 13), STM_PLAT_RESOURCE_DMA_NAMED("tx_half_empty", 17), }, .dev.platform_data = &(struct stm_plat_asc_data) { /* .pad_config set in stx7105_configure_asc() */ }, }, [3] = { .name = "stm-asc", /* .id set in stx7105_configure_asc() */ .num_resources = 4, .resource = (struct resource[]) { STM_PLAT_RESOURCE_MEM(0xfd033000, 0x2c), STM_PLAT_RESOURCE_IRQ(evt2irq(0x1100), -1), STM_PLAT_RESOURCE_DMA_NAMED("rx_half_full", 14), STM_PLAT_RESOURCE_DMA_NAMED("tx_half_empty", 18), }, .dev.platform_data = &(struct stm_plat_asc_data) { .pad_config = &stx7105_asc3_pio5_pad_config, }, }, }; /* Note these three variables are global, and shared with the stasc driver * for console bring up prior to platform initialisation. */ /* the serial console device */ int __initdata stm_asc_console_device; /* Platform devices to register */ unsigned int __initdata stm_asc_configured_devices_num = 0; struct platform_device __initdata *stm_asc_configured_devices[ARRAY_SIZE(stx7105_asc_devices)]; void __init stx7105_configure_asc(int asc, struct stx7105_asc_config *config) { static int configured[ARRAY_SIZE(stx7105_asc_devices)]; static int tty_id; struct stx7105_asc_config default_config = {}; struct platform_device *pdev; struct stm_plat_asc_data *plat_data; BUG_ON(asc < 0 || asc >= ARRAY_SIZE(stx7105_asc_devices)); BUG_ON(configured[asc]); configured[asc] = 1; if (!config) config = &default_config; pdev = &stx7105_asc_devices[asc]; plat_data = pdev->dev.platform_data; pdev->id = tty_id++; plat_data->hw_flow_control = config->hw_flow_control; if (cpu_data->type == CPU_STX7106) plat_data->txfifo_bug = 1; if (asc == 2) { switch (config->routing.asc2) { case stx7105_asc2_pio4: plat_data->pad_config = &stx7105_asc2_pio4_pad_config; break; case stx7105_asc2_pio12: if (cpu_data->type == CPU_STX7106) plat_data->pad_config = &stx7106_asc2_pio12_pad_config; else plat_data->pad_config = &stx7105_asc2_pio12_pad_config; break; default: BUG(); break; } } if (!config->hw_flow_control) { struct stm_pad_config *pad_config = plat_data->pad_config; stm_pad_set_pio_ignored(pad_config, "RTS"); stm_pad_set_pio_ignored(pad_config, "CTS"); if (asc == 2) pad_config->sysconfs_num--; } if (config->is_console) stm_asc_console_device = pdev->id; stm_asc_configured_devices[stm_asc_configured_devices_num++] = pdev; } /* Add platform device as configured by board specific code */ static int __init stx7105_add_asc(void) { return platform_add_devices(stm_asc_configured_devices, stm_asc_configured_devices_num); } arch_initcall(stx7105_add_asc); /* SSC resources ---------------------------------------------------------- */ /* Pad configuration for I2C mode */ static struct stm_pad_config stx7105_ssc_i2c_pad_configs[] = { [0] = { .gpios_num = 2, .gpios = (struct stm_pad_gpio []) { STM_PAD_PIO_BIDIR_NAMED(2, 2, 3, "SCL"), STM_PAD_PIO_BIDIR_NAMED(2, 3, 3, "SDA"), }, }, [1] = { .gpios_num = 2, .gpios = (struct stm_pad_gpio []) { STM_PAD_PIO_BIDIR_NAMED(2, 5, 3, "SCL"), STM_PAD_PIO_BIDIR_NAMED(2, 6, 3, "SDA"), }, }, /* Configurations for SSC2 & SSC3 are created in * stx7105_configure_ssc_*(), according to passed routing * information */ }; /* Pad configuration for SPI mode */ static struct stm_pad_config stx7105_ssc_spi_pad_configs[] = { [0] = { .gpios_num = 3, .gpios = (struct stm_pad_gpio []) { STM_PAD_PIO_OUT(2, 2, 3), /* SCK */ STM_PAD_PIO_OUT(2, 3, 3), /* MOSI */ STM_PAD_PIO_IN(2, 4, -1), /* MISO */ }, .sysconfs_num = 1, .sysconfs = (struct stm_pad_sysconf []) { /* ssc0_mrst_in_sel: 0 = PIO2.3, 1 = PIO2.4 */ STM_PAD_SYS_CFG(16, 0, 0, 1), }, }, [1] = { .gpios_num = 3, .gpios = (struct stm_pad_gpio []) { STM_PAD_PIO_OUT(2, 5, 3), /* SCK */ STM_PAD_PIO_OUT(2, 6, 3), /* MOSI */ STM_PAD_PIO_IN(2, 7, -1), /* MISO */ }, .sysconfs_num = 1, .sysconfs = (struct stm_pad_sysconf []) { /* ssc1_mrst_in_sel: 0 = PIO2.6, 1 = PIO2.7 */ STM_PAD_SYS_CFG(16, 3, 3, 1), }, }, /* Configurations for SSC2 & SSC3 are created in * stx7105_configure_ssc_*(), according to passed routing * information */ }; static struct platform_device stx7105_ssc_devices[] = { [0] = { /* .name & .id set in stx7105_configure_ssc_*() */ .num_resources = 2, .resource = (struct resource[]) { STM_PLAT_RESOURCE_MEM(0xfd040000, 0x110), STM_PLAT_RESOURCE_IRQ(evt2irq(0x10e0), -1), }, .dev.platform_data = &(struct stm_plat_ssc_data) { /* .pad_config_* set in stx7105_configure_ssc_*() */ }, }, [1] = { /* .name & .id set in stx7105_configure_ssc_*() */ .num_resources = 2, .resource = (struct resource[]) { STM_PLAT_RESOURCE_MEM(0xfd041000, 0x110), STM_PLAT_RESOURCE_IRQ(evt2irq(0x10c0), -1), }, .dev.platform_data = &(struct stm_plat_ssc_data) { /* .pad_config_* set in stx7105_configure_ssc_*() */ }, }, [2] = { /* .name & .id set in stx7105_configure_ssc_*() */ .num_resources = 2, .resource = (struct resource[]) { STM_PLAT_RESOURCE_MEM(0xfd042000, 0x110), STM_PLAT_RESOURCE_IRQ(evt2irq(0x10a0), -1), }, .dev.platform_data = &(struct stm_plat_ssc_data) { /* .pad_config_* set in stx7105_configure_ssc_*() */ }, }, [3] = { /* .name & .id set in stx7105_configure_ssc_*() */ .num_resources = 2, .resource = (struct resource[]) { STM_PLAT_RESOURCE_MEM(0xfd043000, 0x110), STM_PLAT_RESOURCE_IRQ(evt2irq(0x1080), -1), }, .dev.platform_data = &(struct stm_plat_ssc_data) { /* .pad_config_* set in stx7105_configure_ssc_*() */ }, }, }; static int __initdata stx7105_ssc_configured[ARRAY_SIZE(stx7105_ssc_devices)]; int __init stx7105_configure_ssc_i2c(int ssc, struct stx7105_ssc_config *config) { static int i2c_busnum; struct stx7105_ssc_config default_config = {}; struct stm_plat_ssc_data *plat_data; struct stm_pad_config *pad_config; BUG_ON(ssc < 0 || ssc >= ARRAY_SIZE(stx7105_ssc_devices)); BUG_ON(stx7105_ssc_configured[ssc]); stx7105_ssc_configured[ssc] = 1; if (!config) config = &default_config; stx7105_ssc_devices[ssc].name = "i2c-stm"; stx7105_ssc_devices[ssc].id = i2c_busnum; plat_data = stx7105_ssc_devices[ssc].dev.platform_data; switch (ssc) { case 0: case 1: pad_config = &stx7105_ssc_i2c_pad_configs[ssc]; break; case 2: pad_config = stm_pad_config_alloc(2, 2); /* SCL */ switch (config->routing.ssc2.sclk) { case stx7105_ssc2_sclk_pio2_4: /* 7106 only! */ BUG_ON(cpu_data->type != CPU_STX7106); stm_pad_config_add_pio_bidir_named(pad_config, 2, 4, 2, "SCL"); /* ssc2_sclk_in: 00 = PIO2.4 */ stm_pad_config_add_sys_cfg(pad_config, 16, 11, 12, 0); break; case stx7105_ssc2_sclk_pio3_4: stm_pad_config_add_pio_bidir_named(pad_config, 3, 4, 2, "SCL"); /* ssc2_sclk_in: 01 = PIO3.4 */ stm_pad_config_add_sys_cfg(pad_config, 16, 11, 12, 1); break; case stx7105_ssc2_sclk_pio12_0: stm_pad_config_add_pio_bidir_named(pad_config, 12, 0, 3, "SCL"); /* ssc2_sclk_in: 10 = PIO12.0 */ stm_pad_config_add_sys_cfg(pad_config, 16, 11, 12, 2); break; case stx7105_ssc2_sclk_pio13_4: stm_pad_config_add_pio_bidir_named(pad_config, 13, 4, 2, "SCL"); /* ssc2_sclk_in: 11 = PIO13.4 */ stm_pad_config_add_sys_cfg(pad_config, 16, 11, 12, 3); break; } /* SDA */ switch (config->routing.ssc2.mtsr) { case stx7105_ssc2_mtsr_pio2_0: stm_pad_config_add_pio_bidir_named(pad_config, 2, 0, 3, "SDA"); /* ssc2_mtsr_in: 00 = PIO2.0 */ stm_pad_config_add_sys_cfg(pad_config, 16, 9, 10, 0); break; case stx7105_ssc2_mtsr_pio3_5: stm_pad_config_add_pio_bidir_named(pad_config, 3, 5, 2, "SDA"); /* ssc2_mtsr_in: 01 = PIO3.5 */ stm_pad_config_add_sys_cfg(pad_config, 16, 9, 10, 1); break; case stx7105_ssc2_mtsr_pio12_1: stm_pad_config_add_pio_bidir_named(pad_config, 12, 1, 3, "SDA"); /* ssc2_mtsr_in: 10 = PIO12.1 */ stm_pad_config_add_sys_cfg(pad_config, 16, 9, 10, 2); break; case stx7105_ssc2_mtsr_pio13_5: stm_pad_config_add_pio_bidir_named(pad_config, 13, 5, 2, "SDA"); /* ssc2_mtsr_in: 11 = PIO13.5 */ stm_pad_config_add_sys_cfg(pad_config, 16, 9, 10, 3); break; } break; case 3: pad_config = stm_pad_config_alloc(2, 2); /* SCL */ switch (config->routing.ssc3.sclk) { case stx7105_ssc3_sclk_pio2_7: /* 7106 only! */ BUG_ON(cpu_data->type != CPU_STX7106); stm_pad_config_add_pio_bidir_named(pad_config, 2, 7, 2, "SCL"); /* ssc3_sclk_in: 00 = PIO2.7 */ stm_pad_config_add_sys_cfg(pad_config, 16, 18, 19, 0); break; case stx7105_ssc3_sclk_pio3_6: stm_pad_config_add_pio_bidir_named(pad_config, 3, 6, 2, "SCL"); /* ssc3_sclk_in: 01 = PIO3.6 */ stm_pad_config_add_sys_cfg(pad_config, 16, 18, 19, 1); break; case stx7105_ssc3_sclk_pio13_2: stm_pad_config_add_pio_bidir_named(pad_config, 13, 2, 4, "SCL"); /* ssc3_sclk_in: 10 = PIO13.2 */ stm_pad_config_add_sys_cfg(pad_config, 16, 18, 19, 2); break; case stx7105_ssc3_sclk_pio13_6: stm_pad_config_add_pio_bidir_named(pad_config, 13, 6, 2, "SCL"); /* ssc3_sclk_in: 11 = PIO13.6 */ stm_pad_config_add_sys_cfg(pad_config, 16, 18, 19, 3); break; } /* SDA */ switch (config->routing.ssc3.mtsr) { case stx7105_ssc3_mtsr_pio2_1: stm_pad_config_add_pio_bidir_named(pad_config, 2, 1, 3, "SDA"); /* ssc3_mtsr_in: 00 = PIO2.1 */ stm_pad_config_add_sys_cfg(pad_config, 16, 16, 17, 0); break; case stx7105_ssc3_mtsr_pio3_7: stm_pad_config_add_pio_bidir_named(pad_config, 3, 7, 2, "SDA"); /* ssc3_mtsr_in: 01 = PIO3.7 */ stm_pad_config_add_sys_cfg(pad_config, 16, 16, 17, 1); break; case stx7105_ssc3_mtsr_pio13_3: stm_pad_config_add_pio_bidir_named(pad_config, 13, 3, 4, "SDA"); /* ssc3_mtsr_in: 10 = PIO13.3 */ stm_pad_config_add_sys_cfg(pad_config, 16, 16, 17, 2); break; case stx7105_ssc3_mtsr_pio13_7: stm_pad_config_add_pio_bidir_named(pad_config, 13, 7, 2, "SDA"); /* ssc3_mtsr_in: 11 = PIO13.7 */ stm_pad_config_add_sys_cfg(pad_config, 16, 16, 17, 3); break; } break; default: BUG(); pad_config = NULL; /* Keep the compiler happy ;-) */ break; } plat_data->pad_config = pad_config; /* I2C bus number reservation (to prevent any hot-plug device * from using it) */ i2c_register_board_info(i2c_busnum, NULL, 0); platform_device_register(&stx7105_ssc_devices[ssc]); return i2c_busnum++; } int __init stx7105_configure_ssc_spi(int ssc, struct stx7105_ssc_config *config) { static int spi_busnum; struct stx7105_ssc_config default_config = {}; struct stm_plat_ssc_data *plat_data; struct stm_pad_config *pad_config; BUG_ON(ssc < 0 || ssc >= ARRAY_SIZE(stx7105_ssc_devices)); BUG_ON(stx7105_ssc_configured[ssc]); stx7105_ssc_configured[ssc] = 1; if (!config) config = &default_config; stx7105_ssc_devices[ssc].name = "spi-stm"; stx7105_ssc_devices[ssc].id = spi_busnum; plat_data = stx7105_ssc_devices[ssc].dev.platform_data; switch (ssc) { case 0: case 1: pad_config = &stx7105_ssc_spi_pad_configs[ssc]; break; case 2: pad_config = stm_pad_config_alloc(3, 2); /* SCK */ switch (config->routing.ssc2.sclk) { case stx7105_ssc2_sclk_pio2_4: /* 7106 only! */ BUG_ON(cpu_data->type != CPU_STX7106); stm_pad_config_add_pio_out(pad_config, 2, 4, 2); /* ssc2_sclk_in: 00 = PIO2.4 */ stm_pad_config_add_sys_cfg(pad_config, 16, 11, 12, 0); break; case stx7105_ssc2_sclk_pio3_4: stm_pad_config_add_pio_out(pad_config, 3, 4, 2); /* ssc2_sclk_in: 01 = PIO3.4 */ stm_pad_config_add_sys_cfg(pad_config, 16, 11, 12, 1); break; case stx7105_ssc2_sclk_pio12_0: stm_pad_config_add_pio_out(pad_config, 12, 0, 3); /* ssc2_sclk_in: 10 = PIO12.0 */ stm_pad_config_add_sys_cfg(pad_config, 16, 11, 12, 2); break; case stx7105_ssc2_sclk_pio13_4: stm_pad_config_add_pio_out(pad_config, 13, 4, 2); /* ssc2_sclk_in: 11 = PIO13.4 */ stm_pad_config_add_sys_cfg(pad_config, 16, 11, 12, 3); break; } /* MOSI */ switch (config->routing.ssc2.mtsr) { case stx7105_ssc2_mtsr_pio2_0: stm_pad_config_add_pio_out(pad_config, 2, 0, 3); break; case stx7105_ssc2_mtsr_pio3_5: stm_pad_config_add_pio_out(pad_config, 3, 5, 2); break; case stx7105_ssc2_mtsr_pio12_1: stm_pad_config_add_pio_out(pad_config, 12, 1, 3); break; case stx7105_ssc2_mtsr_pio13_5: stm_pad_config_add_pio_out(pad_config, 13, 5, 2); break; } /* MISO */ switch (config->routing.ssc2.mrst) { case stx7105_ssc2_mrst_pio2_0: stm_pad_config_add_pio_in(pad_config, 2, 0, -1); /* ssc2_mrst_in: 00 = PIO2.0 */ stm_pad_config_add_sys_cfg(pad_config, 16, 7, 8, 0); break; case stx7105_ssc2_mrst_pio3_5: stm_pad_config_add_pio_in(pad_config, 3, 5, -1); /* ssc2_mrst_in: 01 = PIO3.5 */ stm_pad_config_add_sys_cfg(pad_config, 16, 7, 8, 1); break; case stx7105_ssc2_mrst_pio12_1: stm_pad_config_add_pio_in(pad_config, 12, 1, -1); /* ssc2_mrst_in: 10 = PIO12.1 */ stm_pad_config_add_sys_cfg(pad_config, 16, 7, 8, 2); break; case stx7105_ssc2_mrst_pio13_5: stm_pad_config_add_pio_in(pad_config, 13, 5, -1); /* ssc2_mrst_in: 11 = PIO13.5 */ stm_pad_config_add_sys_cfg(pad_config, 16, 7, 8, 3); break; } break; case 3: pad_config = stm_pad_config_alloc(3, 2); /* SCK */ switch (config->routing.ssc3.sclk) { case stx7105_ssc3_sclk_pio2_7: /* 7106 only! */ BUG_ON(cpu_data->type != CPU_STX7106); stm_pad_config_add_pio_out(pad_config, 2, 7, 2); /* ssc3_sclk_in: 00 = PIO2.7 */ stm_pad_config_add_sys_cfg(pad_config, 16, 18, 19, 0); break; case stx7105_ssc3_sclk_pio3_6: stm_pad_config_add_pio_out(pad_config, 3, 6, 2); /* ssc3_sclk_in: 00 = PIO3.6 */ stm_pad_config_add_sys_cfg(pad_config, 16, 18, 19, 0); break; case stx7105_ssc3_sclk_pio13_2: stm_pad_config_add_pio_out(pad_config, 13, 2, 4); /* ssc3_sclk_in: 01 = PIO13.2 */ stm_pad_config_add_sys_cfg(pad_config, 16, 18, 19, 1); break; case stx7105_ssc3_sclk_pio13_6: stm_pad_config_add_pio_out(pad_config, 13, 6, 2); /* ssc3_sclk_in: 1x = PIO13.6 */ stm_pad_config_add_sys_cfg(pad_config, 16, 18, 19, 2); break; } /* MOSI */ switch (config->routing.ssc3.mtsr) { case stx7105_ssc3_mtsr_pio2_1: stm_pad_config_add_pio_out(pad_config, 2, 1, 3); break; case stx7105_ssc3_mtsr_pio3_7: stm_pad_config_add_pio_out(pad_config, 3, 7, 3); break; case stx7105_ssc3_mtsr_pio13_3: stm_pad_config_add_pio_out(pad_config, 13, 3, 4); break; case stx7105_ssc3_mtsr_pio13_7: stm_pad_config_add_pio_out(pad_config, 13, 7, 2); break; } /* MISO */ switch (config->routing.ssc3.mrst) { case stx7105_ssc3_mrst_pio2_1: stm_pad_config_add_pio_in(pad_config, 2, 1, -1); /* ssc3_mrst_in: 00 = PIO2.1 */ stm_pad_config_add_sys_cfg(pad_config, 16, 14, 15, 0); break; case stx7105_ssc3_mrst_pio3_7: stm_pad_config_add_pio_in(pad_config, 3, 7, -1); /* ssc3_mrst_in: 01 = PIO3.7 */ stm_pad_config_add_sys_cfg(pad_config, 16, 14, 15, 1); break; case stx7105_ssc3_mrst_pio13_3: stm_pad_config_add_pio_in(pad_config, 13, 3, -1); /* ssc3_mrst_in: 10 = PIO13.3 */ stm_pad_config_add_sys_cfg(pad_config, 16, 14, 15, 2); break; case stx7105_ssc3_mrst_pio13_7: stm_pad_config_add_pio_in(pad_config, 13, 7, -1); /* ssc3_mrst_in: 11 = PIO13.7 */ stm_pad_config_add_sys_cfg(pad_config, 16, 14, 15, 3); break; } break; default: BUG(); pad_config = NULL; /* Keep the compiler happy ;-) */ break; } plat_data->spi_chipselect = config->spi_chipselect; plat_data->pad_config = pad_config; platform_device_register(&stx7105_ssc_devices[ssc]); return spi_busnum++; } /* LiRC resources --------------------------------------------------------- */ static struct platform_device stx7105_lirc_device = { .name = "lirc-stm", .id = -1, .num_resources = 2, .resource = (struct resource []) { STM_PLAT_RESOURCE_MEM(0xfd018000, 0x234), STM_PLAT_RESOURCE_IRQ(evt2irq(0x11a0), -1), }, .dev.platform_data = &(struct stm_plat_lirc_data) { /* The clock settings will be calculated by * the driver from the system clock */ .irbclock = 0, /* use current_cpu data */ .irbclkdiv = 0, /* automatically calculate */ .irbperiodmult = 0, .irbperioddiv = 0, .irbontimemult = 0, .irbontimediv = 0, .irbrxmaxperiod = 0x5000, .sysclkdiv = 1, .rxpolarity = 1, }, }; void __init stx7105_configure_lirc(struct stx7105_lirc_config *config) { static int configured; struct stx7105_lirc_config default_config = {}; struct stm_plat_lirc_data *plat_data = stx7105_lirc_device.dev.platform_data; struct stm_pad_config *pad_config; BUG_ON(configured); configured = 1; if (!config) config = &default_config; pad_config = stm_pad_config_alloc(3, 0); BUG_ON(!pad_config); plat_data->txenabled = config->tx_enabled || config->tx_od_enabled; plat_data->pads = pad_config; switch (config->rx_mode) { case stx7105_lirc_rx_disabled: /* Nothing to do */ break; case stx7105_lirc_rx_mode_ir: plat_data->rxuhfmode = 0; stm_pad_config_add_pio_in(pad_config, 3, 0, -1); break; case stx7105_lirc_rx_mode_uhf: plat_data->rxuhfmode = 1; stm_pad_config_add_pio_in(pad_config, 3, 1, -1); break; default: BUG(); break; } if (config->tx_enabled) stm_pad_config_add_pio_out(pad_config, 3, 2, 3); if (config->tx_od_enabled) stm_pad_config_add_pio_out(pad_config, 3, 3, 3); platform_device_register(&stx7105_lirc_device); } /* PWM resources ---------------------------------------------------------- */ static struct stm_pad_config stx7105_pwm_out0_pio4_4_pad_config = { .gpios_num = 1, .gpios = (struct stm_pad_gpio []) { STM_PAD_PIO_OUT(4, 4, 3), }, }; static struct stm_pad_config stx7105_pwm_out0_pio13_0_pad_config = { .gpios_num = 1, .gpios = (struct stm_pad_gpio []) { STM_PAD_PIO_OUT(13, 0, 3), }, }; static struct stm_pad_config stx7105_pwm_out1_pio4_5_pad_config = { .gpios_num = 1, .gpios = (struct stm_pad_gpio []) { STM_PAD_PIO_OUT(4, 5, 3), }, }; static struct stm_pad_config stx7105_pwm_out1_pio13_1_pad_config = { .gpios_num = 1, .gpios = (struct stm_pad_gpio []) { STM_PAD_PIO_OUT(13, 1, 3), }, }; /* Set in stx7105_configure_pwm() */ static struct stm_plat_pwm_data stx7105_pwm_platform_data; static struct platform_device stx7105_pwm_device = { .name = "stm-pwm", .id = -1, .num_resources = 2, .resource = (struct resource[]) { STM_PLAT_RESOURCE_MEM(0xfd010000, 0x68), STM_PLAT_RESOURCE_IRQ(evt2irq(0x11c0), -1), }, .dev.platform_data = &stx7105_pwm_platform_data, }; void __init stx7105_configure_pwm(struct stx7105_pwm_config *config) { static int configured; BUG_ON(configured); configured = 1; if (config) { switch (config->out0) { case stx7105_pwm_out0_disabled: /* Nothing to do... */ break; case stx7105_pwm_out0_pio4_4: stx7105_pwm_platform_data.channel_enabled[0] = 1; stx7105_pwm_platform_data.channel_pad_config[0] = &stx7105_pwm_out0_pio4_4_pad_config; break; case stx7105_pwm_out0_pio13_0: stx7105_pwm_platform_data.channel_enabled[0] = 1; stx7105_pwm_platform_data.channel_pad_config[0] = &stx7105_pwm_out0_pio13_0_pad_config; break; default: BUG(); break; } switch (config->out1) { case stx7105_pwm_out1_disabled: /* Nothing to do... */ break; case stx7105_pwm_out1_pio4_5: stx7105_pwm_platform_data.channel_enabled[1] = 1; stx7105_pwm_platform_data.channel_pad_config[1] = &stx7105_pwm_out1_pio4_5_pad_config; break; case stx7105_pwm_out1_pio13_1: stx7105_pwm_platform_data.channel_enabled[1] = 1; stx7105_pwm_platform_data.channel_pad_config[1] = &stx7105_pwm_out1_pio13_1_pad_config; break; default: BUG(); break; } } platform_device_register(&stx7105_pwm_device); } /* Low Power Controller ---------------------------------------------------- */ static struct platform_device stx7105_lpc_device = { .name = "stm-rtc", .id = -1, .num_resources = 2, .resource = (struct resource[]){ STM_PLAT_RESOURCE_MEM(0xfd008000, 0x600), STM_PLAT_RESOURCE_IRQ(ILC_EXT_IRQ(7), -1), }, .dev.platform_data = &(struct stm_plat_rtc_lpc) { .clk_id = "CLKB_LPC", .need_wdt_reset = 1, .irq_edge_level = IRQ_TYPE_EDGE_FALLING, } }; static int __init stx7105_add_lpc(void) { return platform_device_register(&stx7105_lpc_device); } module_init(stx7105_add_lpc);