|
@@ -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>
|
|
@@ -162,6 +163,22 @@ inline static void pxa_irda_fir_dma_tx_start(struct pxa_irda *si)
|
|
|
DCSR(si->txdma) |= DCSR_RUN;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * 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.
|
|
|
*/
|
|
@@ -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);
|