diff options
Diffstat (limited to 'drivers/net/irda/pxaficp_ir.c')
-rw-r--r-- | drivers/net/irda/pxaficp_ir.c | 47 |
1 files changed, 41 insertions, 6 deletions
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index 77d10ed..f5b7d83 100644 --- a/drivers/net/irda/pxaficp_ir.c +++ b/drivers/net/irda/pxaficp_ir.c @@ -17,6 +17,7 @@ #include <linux/etherdevice.h> #include <linux/platform_device.h> #include <linux/clk.h> +#include <linux/gpio.h> #include <net/irda/irda.h> #include <net/irda/irmod.h> @@ -163,6 +164,22 @@ inline static void pxa_irda_fir_dma_tx_start(struct pxa_irda *si) } /* + * Set the IrDA communications mode. + */ +static void pxa_irda_set_mode(struct pxa_irda *si, int mode) +{ + if (si->pdata->transceiver_mode) + si->pdata->transceiver_mode(si->dev, mode); + else { + if (gpio_is_valid(si->pdata->gpio_pwdown)) + gpio_set_value(si->pdata->gpio_pwdown, + !(mode & IR_OFF) ^ + !si->pdata->gpio_pwdown_inverted); + pxa2xx_transceiver_mode(si->dev, mode); + } +} + +/* * Set the IrDA communications speed. */ static int pxa_irda_set_speed(struct pxa_irda *si, int speed) @@ -188,7 +205,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed) pxa_irda_disable_clk(si); /* set board transceiver to SIR mode */ - si->pdata->transceiver_mode(si->dev, IR_SIRMODE); + pxa_irda_set_mode(si, IR_SIRMODE); /* enable the STUART clock */ pxa_irda_enable_sirclk(si); @@ -222,7 +239,7 @@ static int pxa_irda_set_speed(struct pxa_irda *si, int speed) ICCR0 = 0; /* set board transceiver to FIR mode */ - si->pdata->transceiver_mode(si->dev, IR_FIRMODE); + pxa_irda_set_mode(si, IR_FIRMODE); /* enable the FICP clock */ pxa_irda_enable_firclk(si); @@ -641,7 +658,7 @@ static void pxa_irda_shutdown(struct pxa_irda *si) local_irq_restore(flags); /* power off board transceiver */ - si->pdata->transceiver_mode(si->dev, IR_OFF); + pxa_irda_set_mode(si, IR_OFF); printk(KERN_DEBUG "pxa_ir: irda shutdown\n"); } @@ -849,10 +866,26 @@ static int pxa_irda_probe(struct platform_device *pdev) if (err) goto err_mem_5; - if (si->pdata->startup) + if (gpio_is_valid(si->pdata->gpio_pwdown)) { + err = gpio_request(si->pdata->gpio_pwdown, "IrDA switch"); + if (err) + goto err_startup; + err = gpio_direction_output(si->pdata->gpio_pwdown, + !si->pdata->gpio_pwdown_inverted); + if (err) { + gpio_free(si->pdata->gpio_pwdown); + goto err_startup; + } + } + + if (si->pdata->startup) { err = si->pdata->startup(si->dev); - if (err) - goto err_startup; + if (err) + goto err_startup; + } + + if (gpio_is_valid(si->pdata->gpio_pwdown) && si->pdata->startup) + dev_warn(si->dev, "gpio_pwdown and startup() both defined!\n"); dev->netdev_ops = &pxa_irda_netdev_ops; @@ -903,6 +936,8 @@ static int pxa_irda_remove(struct platform_device *_dev) if (dev) { struct pxa_irda *si = netdev_priv(dev); unregister_netdev(dev); + if (gpio_is_valid(si->pdata->gpio_pwdown)) + gpio_free(si->pdata->gpio_pwdown); if (si->pdata->shutdown) si->pdata->shutdown(si->dev); kfree(si->tx_buff.head); |