X-Git-Url: http://www.pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=arch%2Farm%2Fmach-omap1%2Fboard-h3.c;h=4695965114c4e67e86456439fa4435149e0cf374;hb=81b22a7c709de3ad31595abc49c019e504848e05;hp=f597968733b4f2baa980419519edade5e0203961;hpb=7b4c6760b933f3209747b3d158ac4d78dcfb19d9;p=linux-2.6-omap-h63xx.git diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index f597968733b..4695965114c 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c @@ -39,10 +39,12 @@ #include #include +#include #include #include #include #include +#include #include #include #include @@ -274,6 +276,104 @@ static struct platform_device h3_kp_device = { .resource = h3_kp_resources, }; + +/* Select between the IrDA and aGPS module + */ +static int h3_select_irda(struct device *dev, int state) +{ + unsigned char expa; + int err = 0; + + if ((err = read_gpio_expa(&expa, 0x26))) { + printk(KERN_ERR "Error reading from I/O EXPANDER \n"); + return err; + } + + /* 'P6' enable/disable IRDA_TX and IRDA_RX */ + if (state & IR_SEL) { /* IrDA */ + if ((err = write_gpio_expa(expa | 0x40, 0x26))) { + printk(KERN_ERR "Error writing to I/O EXPANDER \n"); + return err; + } + } else { + if ((err = write_gpio_expa(expa & ~0x40, 0x26))) { + printk(KERN_ERR "Error writing to I/O EXPANDER \n"); + return err; + } + } + return err; +} + +static void set_trans_mode(struct work_struct *work) +{ + struct omap_irda_config *irda_config = + container_of(work, struct omap_irda_config, gpio_expa.work); + int mode = irda_config->mode; + unsigned char expa; + int err = 0; + + if ((err = read_gpio_expa(&expa, 0x27)) != 0) { + printk(KERN_ERR "Error reading from I/O expander\n"); + } + + expa &= ~0x03; + + if (mode & IR_SIRMODE) { + expa |= 0x01; + } else { /* MIR/FIR */ + expa |= 0x03; + } + + if ((err = write_gpio_expa(expa, 0x27)) != 0) { + printk(KERN_ERR "Error writing to I/O expander\n"); + } +} + +static int h3_transceiver_mode(struct device *dev, int mode) +{ + struct omap_irda_config *irda_config = dev->platform_data; + + irda_config->mode = mode; + cancel_delayed_work(&irda_config->gpio_expa); + PREPARE_DELAYED_WORK(&irda_config->gpio_expa, set_trans_mode); + schedule_delayed_work(&irda_config->gpio_expa, 0); + + return 0; +} + +static struct omap_irda_config h3_irda_data = { + .transceiver_cap = IR_SIRMODE | IR_MIRMODE | IR_FIRMODE, + .transceiver_mode = h3_transceiver_mode, + .select_irda = h3_select_irda, + .rx_channel = OMAP_DMA_UART3_RX, + .tx_channel = OMAP_DMA_UART3_TX, + .dest_start = UART3_THR, + .src_start = UART3_RHR, + .tx_trigger = 0, + .rx_trigger = 0, +}; + +static struct resource h3_irda_resources[] = { + [0] = { + .start = INT_UART3, + .end = INT_UART3, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 irda_dmamask = 0xffffffff; + +static struct platform_device h3_irda_device = { + .name = "omapirda", + .id = 0, + .dev = { + .platform_data = &h3_irda_data, + .dma_mask = &irda_dmamask, + }, + .num_resources = ARRAY_SIZE(h3_irda_resources), + .resource = h3_irda_resources, +}; + static struct platform_device h3_lcd_device = { .name = "lcd_h3", .id = -1, @@ -295,6 +395,7 @@ static struct platform_device *devices[] __initdata = { &nand_device, &smc91x_device, &intlat_device, + &h3_irda_device, &h3_kp_device, &h3_lcd_device, };