diff options
author | Antti Palosaari <crope@iki.fi> | 2012-07-19 20:10:36 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-09-27 13:33:58 -0400 |
commit | 1e8f31f31726148c27de1ff4692c76c9bcff9860 (patch) | |
tree | b593d16c49ae28aec06f8e3d42ca8b70d08a7ea6 | |
parent | 75aeafc9d0e21222b876990946ef534b384462f1 (diff) |
[media] cxd2820r: use Kernel GPIO for GPIO access
Currently there is LNA behind cxd2820r demodulator GPIO. Use
Kernel GPIO interface to access those GPIOs.
Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/dvb-frontends/cxd2820r.h | 14 | ||||
-rw-r--r-- | drivers/media/dvb-frontends/cxd2820r_c.c | 5 | ||||
-rw-r--r-- | drivers/media/dvb-frontends/cxd2820r_core.c | 108 | ||||
-rw-r--r-- | drivers/media/dvb-frontends/cxd2820r_priv.h | 9 | ||||
-rw-r--r-- | drivers/media/dvb-frontends/cxd2820r_t.c | 5 | ||||
-rw-r--r-- | drivers/media/dvb-frontends/cxd2820r_t2.c | 5 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb-v2/anysee.c | 2 | ||||
-rw-r--r-- | drivers/media/usb/em28xx/em28xx-dvb.c | 21 |
8 files changed, 114 insertions, 55 deletions
diff --git a/drivers/media/dvb-frontends/cxd2820r.h b/drivers/media/dvb-frontends/cxd2820r.h index 5aa306ebb7ef..6acc21c581c5 100644 --- a/drivers/media/dvb-frontends/cxd2820r.h +++ b/drivers/media/dvb-frontends/cxd2820r.h | |||
@@ -62,14 +62,6 @@ struct cxd2820r_config { | |||
62 | * Values: 0, 1 | 62 | * Values: 0, 1 |
63 | */ | 63 | */ |
64 | bool spec_inv; | 64 | bool spec_inv; |
65 | |||
66 | /* GPIOs for all used modes. | ||
67 | * Default: none, disabled | ||
68 | * Values: <see above> | ||
69 | */ | ||
70 | u8 gpio_dvbt[3]; | ||
71 | u8 gpio_dvbt2[3]; | ||
72 | u8 gpio_dvbc[3]; | ||
73 | }; | 65 | }; |
74 | 66 | ||
75 | 67 | ||
@@ -77,12 +69,14 @@ struct cxd2820r_config { | |||
77 | (defined(CONFIG_DVB_CXD2820R_MODULE) && defined(MODULE)) | 69 | (defined(CONFIG_DVB_CXD2820R_MODULE) && defined(MODULE)) |
78 | extern struct dvb_frontend *cxd2820r_attach( | 70 | extern struct dvb_frontend *cxd2820r_attach( |
79 | const struct cxd2820r_config *config, | 71 | const struct cxd2820r_config *config, |
80 | struct i2c_adapter *i2c | 72 | struct i2c_adapter *i2c, |
73 | int *gpio_chip_base | ||
81 | ); | 74 | ); |
82 | #else | 75 | #else |
83 | static inline struct dvb_frontend *cxd2820r_attach( | 76 | static inline struct dvb_frontend *cxd2820r_attach( |
84 | const struct cxd2820r_config *config, | 77 | const struct cxd2820r_config *config, |
85 | struct i2c_adapter *i2c | 78 | struct i2c_adapter *i2c, |
79 | int *gpio_chip_base | ||
86 | ) | 80 | ) |
87 | { | 81 | { |
88 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | 82 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); |
diff --git a/drivers/media/dvb-frontends/cxd2820r_c.c b/drivers/media/dvb-frontends/cxd2820r_c.c index d2a0c285840d..125a44041011 100644 --- a/drivers/media/dvb-frontends/cxd2820r_c.c +++ b/drivers/media/dvb-frontends/cxd2820r_c.c | |||
@@ -50,11 +50,6 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe) | |||
50 | dev_dbg(&priv->i2c->dev, "%s: frequency=%d symbol_rate=%d\n", __func__, | 50 | dev_dbg(&priv->i2c->dev, "%s: frequency=%d symbol_rate=%d\n", __func__, |
51 | c->frequency, c->symbol_rate); | 51 | c->frequency, c->symbol_rate); |
52 | 52 | ||
53 | /* update GPIOs */ | ||
54 | ret = cxd2820r_gpio(fe); | ||
55 | if (ret) | ||
56 | goto error; | ||
57 | |||
58 | /* program tuner */ | 53 | /* program tuner */ |
59 | if (fe->ops.tuner_ops.set_params) | 54 | if (fe->ops.tuner_ops.set_params) |
60 | fe->ops.tuner_ops.set_params(fe); | 55 | fe->ops.tuner_ops.set_params(fe); |
diff --git a/drivers/media/dvb-frontends/cxd2820r_core.c b/drivers/media/dvb-frontends/cxd2820r_core.c index a3656ba67d77..4bd42f20d5b3 100644 --- a/drivers/media/dvb-frontends/cxd2820r_core.c +++ b/drivers/media/dvb-frontends/cxd2820r_core.c | |||
@@ -168,30 +168,15 @@ int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val, | |||
168 | return cxd2820r_wr_reg(priv, reg, val); | 168 | return cxd2820r_wr_reg(priv, reg, val); |
169 | } | 169 | } |
170 | 170 | ||
171 | int cxd2820r_gpio(struct dvb_frontend *fe) | 171 | int cxd2820r_gpio(struct dvb_frontend *fe, u8 *gpio) |
172 | { | 172 | { |
173 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 173 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
174 | int ret, i; | 174 | int ret, i; |
175 | u8 *gpio, tmp0, tmp1; | 175 | u8 tmp0, tmp1; |
176 | 176 | ||
177 | dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__, | 177 | dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__, |
178 | fe->dtv_property_cache.delivery_system); | 178 | fe->dtv_property_cache.delivery_system); |
179 | 179 | ||
180 | switch (fe->dtv_property_cache.delivery_system) { | ||
181 | case SYS_DVBT: | ||
182 | gpio = priv->cfg.gpio_dvbt; | ||
183 | break; | ||
184 | case SYS_DVBT2: | ||
185 | gpio = priv->cfg.gpio_dvbt2; | ||
186 | break; | ||
187 | case SYS_DVBC_ANNEX_AC: | ||
188 | gpio = priv->cfg.gpio_dvbc; | ||
189 | break; | ||
190 | default: | ||
191 | ret = -EINVAL; | ||
192 | goto error; | ||
193 | } | ||
194 | |||
195 | /* update GPIOs only when needed */ | 180 | /* update GPIOs only when needed */ |
196 | if (!memcmp(gpio, priv->gpio, sizeof(priv->gpio))) | 181 | if (!memcmp(gpio, priv->gpio, sizeof(priv->gpio))) |
197 | return 0; | 182 | return 0; |
@@ -582,9 +567,19 @@ static int cxd2820r_get_frontend_algo(struct dvb_frontend *fe) | |||
582 | static void cxd2820r_release(struct dvb_frontend *fe) | 567 | static void cxd2820r_release(struct dvb_frontend *fe) |
583 | { | 568 | { |
584 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 569 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
570 | int ret; | ||
585 | 571 | ||
586 | dev_dbg(&priv->i2c->dev, "%s\n", __func__); | 572 | dev_dbg(&priv->i2c->dev, "%s\n", __func__); |
587 | 573 | ||
574 | #ifdef CONFIG_GPIOLIB | ||
575 | /* remove GPIOs */ | ||
576 | if (priv->gpio_chip.label) { | ||
577 | ret = gpiochip_remove(&priv->gpio_chip); | ||
578 | if (ret) | ||
579 | dev_err(&priv->i2c->dev, "%s: gpiochip_remove() " \ | ||
580 | "failed=%d\n", KBUILD_MODNAME, ret); | ||
581 | } | ||
582 | #endif | ||
588 | kfree(priv); | 583 | kfree(priv); |
589 | return; | 584 | return; |
590 | } | 585 | } |
@@ -599,6 +594,49 @@ static int cxd2820r_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) | |||
599 | return cxd2820r_wr_reg_mask(priv, 0xdb, enable ? 1 : 0, 0x1); | 594 | return cxd2820r_wr_reg_mask(priv, 0xdb, enable ? 1 : 0, 0x1); |
600 | } | 595 | } |
601 | 596 | ||
597 | #ifdef CONFIG_GPIOLIB | ||
598 | static int cxd2820r_gpio_direction_output(struct gpio_chip *chip, unsigned nr, | ||
599 | int val) | ||
600 | { | ||
601 | struct cxd2820r_priv *priv = | ||
602 | container_of(chip, struct cxd2820r_priv, gpio_chip); | ||
603 | u8 gpio[GPIO_COUNT]; | ||
604 | |||
605 | dev_dbg(&priv->i2c->dev, "%s: nr=%d val=%d\n", __func__, nr, val); | ||
606 | |||
607 | memcpy(gpio, priv->gpio, sizeof(gpio)); | ||
608 | gpio[nr] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | (val << 2); | ||
609 | |||
610 | return cxd2820r_gpio(&priv->fe, gpio); | ||
611 | } | ||
612 | |||
613 | static void cxd2820r_gpio_set(struct gpio_chip *chip, unsigned nr, int val) | ||
614 | { | ||
615 | struct cxd2820r_priv *priv = | ||
616 | container_of(chip, struct cxd2820r_priv, gpio_chip); | ||
617 | u8 gpio[GPIO_COUNT]; | ||
618 | |||
619 | dev_dbg(&priv->i2c->dev, "%s: nr=%d val=%d\n", __func__, nr, val); | ||
620 | |||
621 | memcpy(gpio, priv->gpio, sizeof(gpio)); | ||
622 | gpio[nr] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | (val << 2); | ||
623 | |||
624 | (void) cxd2820r_gpio(&priv->fe, gpio); | ||
625 | |||
626 | return; | ||
627 | } | ||
628 | |||
629 | static int cxd2820r_gpio_get(struct gpio_chip *chip, unsigned nr) | ||
630 | { | ||
631 | struct cxd2820r_priv *priv = | ||
632 | container_of(chip, struct cxd2820r_priv, gpio_chip); | ||
633 | |||
634 | dev_dbg(&priv->i2c->dev, "%s: nr=%d\n", __func__, nr); | ||
635 | |||
636 | return (priv->gpio[nr] >> 2) & 0x01; | ||
637 | } | ||
638 | #endif | ||
639 | |||
602 | static const struct dvb_frontend_ops cxd2820r_ops = { | 640 | static const struct dvb_frontend_ops cxd2820r_ops = { |
603 | .delsys = { SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A }, | 641 | .delsys = { SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A }, |
604 | /* default: DVB-T/T2 */ | 642 | /* default: DVB-T/T2 */ |
@@ -645,15 +683,20 @@ static const struct dvb_frontend_ops cxd2820r_ops = { | |||
645 | }; | 683 | }; |
646 | 684 | ||
647 | struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg, | 685 | struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg, |
648 | struct i2c_adapter *i2c) | 686 | struct i2c_adapter *i2c, int *gpio_chip_base |
687 | ) | ||
649 | { | 688 | { |
650 | struct cxd2820r_priv *priv = NULL; | 689 | struct cxd2820r_priv *priv; |
651 | int ret; | 690 | int ret; |
652 | u8 tmp; | 691 | u8 tmp; |
653 | 692 | ||
654 | priv = kzalloc(sizeof (struct cxd2820r_priv), GFP_KERNEL); | 693 | priv = kzalloc(sizeof (struct cxd2820r_priv), GFP_KERNEL); |
655 | if (!priv) | 694 | if (!priv) { |
695 | ret = -ENOMEM; | ||
696 | dev_err(&i2c->dev, "%s: kzalloc() failed\n", | ||
697 | KBUILD_MODNAME); | ||
656 | goto error; | 698 | goto error; |
699 | } | ||
657 | 700 | ||
658 | priv->i2c = i2c; | 701 | priv->i2c = i2c; |
659 | memcpy(&priv->cfg, cfg, sizeof (struct cxd2820r_config)); | 702 | memcpy(&priv->cfg, cfg, sizeof (struct cxd2820r_config)); |
@@ -664,10 +707,35 @@ struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg, | |||
664 | if (ret || tmp != 0xe1) | 707 | if (ret || tmp != 0xe1) |
665 | goto error; | 708 | goto error; |
666 | 709 | ||
710 | #ifdef CONFIG_GPIOLIB | ||
711 | /* add GPIOs */ | ||
712 | if (gpio_chip_base) { | ||
713 | priv->gpio_chip.label = KBUILD_MODNAME; | ||
714 | priv->gpio_chip.dev = &priv->i2c->dev; | ||
715 | priv->gpio_chip.owner = THIS_MODULE; | ||
716 | priv->gpio_chip.direction_output = | ||
717 | cxd2820r_gpio_direction_output; | ||
718 | priv->gpio_chip.set = cxd2820r_gpio_set; | ||
719 | priv->gpio_chip.get = cxd2820r_gpio_get; | ||
720 | priv->gpio_chip.base = -1; /* dynamic allocation */ | ||
721 | priv->gpio_chip.ngpio = GPIO_COUNT; | ||
722 | priv->gpio_chip.can_sleep = 1; | ||
723 | ret = gpiochip_add(&priv->gpio_chip); | ||
724 | if (ret) | ||
725 | goto error; | ||
726 | |||
727 | dev_dbg(&priv->i2c->dev, "%s: gpio_chip.base=%d\n", __func__, | ||
728 | priv->gpio_chip.base); | ||
729 | |||
730 | *gpio_chip_base = priv->gpio_chip.base; | ||
731 | } | ||
732 | #endif | ||
733 | |||
667 | memcpy(&priv->fe.ops, &cxd2820r_ops, sizeof (struct dvb_frontend_ops)); | 734 | memcpy(&priv->fe.ops, &cxd2820r_ops, sizeof (struct dvb_frontend_ops)); |
668 | priv->fe.demodulator_priv = priv; | 735 | priv->fe.demodulator_priv = priv; |
669 | return &priv->fe; | 736 | return &priv->fe; |
670 | error: | 737 | error: |
738 | dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret); | ||
671 | kfree(priv); | 739 | kfree(priv); |
672 | return NULL; | 740 | return NULL; |
673 | } | 741 | } |
diff --git a/drivers/media/dvb-frontends/cxd2820r_priv.h b/drivers/media/dvb-frontends/cxd2820r_priv.h index 9396492119ca..7ff5f60c83e1 100644 --- a/drivers/media/dvb-frontends/cxd2820r_priv.h +++ b/drivers/media/dvb-frontends/cxd2820r_priv.h | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "dvb_frontend.h" | 26 | #include "dvb_frontend.h" |
27 | #include "dvb_math.h" | 27 | #include "dvb_math.h" |
28 | #include "cxd2820r.h" | 28 | #include "cxd2820r.h" |
29 | #include <linux/gpio.h> | ||
29 | 30 | ||
30 | struct reg_val_mask { | 31 | struct reg_val_mask { |
31 | u32 reg; | 32 | u32 reg; |
@@ -41,7 +42,11 @@ struct cxd2820r_priv { | |||
41 | bool ber_running; | 42 | bool ber_running; |
42 | 43 | ||
43 | u8 bank[2]; | 44 | u8 bank[2]; |
44 | u8 gpio[3]; | 45 | #define GPIO_COUNT 3 |
46 | u8 gpio[GPIO_COUNT]; | ||
47 | #ifdef CONFIG_GPIOLIB | ||
48 | struct gpio_chip gpio_chip; | ||
49 | #endif | ||
45 | 50 | ||
46 | fe_delivery_system_t delivery_system; | 51 | fe_delivery_system_t delivery_system; |
47 | bool last_tune_failed; /* for switch between T and T2 tune */ | 52 | bool last_tune_failed; /* for switch between T and T2 tune */ |
@@ -51,7 +56,7 @@ struct cxd2820r_priv { | |||
51 | 56 | ||
52 | extern int cxd2820r_debug; | 57 | extern int cxd2820r_debug; |
53 | 58 | ||
54 | int cxd2820r_gpio(struct dvb_frontend *fe); | 59 | int cxd2820r_gpio(struct dvb_frontend *fe, u8 *gpio); |
55 | 60 | ||
56 | int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val, | 61 | int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val, |
57 | u8 mask); | 62 | u8 mask); |
diff --git a/drivers/media/dvb-frontends/cxd2820r_t.c b/drivers/media/dvb-frontends/cxd2820r_t.c index af5890e4f837..fa184ca2dd68 100644 --- a/drivers/media/dvb-frontends/cxd2820r_t.c +++ b/drivers/media/dvb-frontends/cxd2820r_t.c | |||
@@ -74,11 +74,6 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe) | |||
74 | return -EINVAL; | 74 | return -EINVAL; |
75 | } | 75 | } |
76 | 76 | ||
77 | /* update GPIOs */ | ||
78 | ret = cxd2820r_gpio(fe); | ||
79 | if (ret) | ||
80 | goto error; | ||
81 | |||
82 | /* program tuner */ | 77 | /* program tuner */ |
83 | if (fe->ops.tuner_ops.set_params) | 78 | if (fe->ops.tuner_ops.set_params) |
84 | fe->ops.tuner_ops.set_params(fe); | 79 | fe->ops.tuner_ops.set_params(fe); |
diff --git a/drivers/media/dvb-frontends/cxd2820r_t2.c b/drivers/media/dvb-frontends/cxd2820r_t2.c index 653c56eb065b..e82d82a7a2eb 100644 --- a/drivers/media/dvb-frontends/cxd2820r_t2.c +++ b/drivers/media/dvb-frontends/cxd2820r_t2.c | |||
@@ -92,11 +92,6 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe) | |||
92 | return -EINVAL; | 92 | return -EINVAL; |
93 | } | 93 | } |
94 | 94 | ||
95 | /* update GPIOs */ | ||
96 | ret = cxd2820r_gpio(fe); | ||
97 | if (ret) | ||
98 | goto error; | ||
99 | |||
100 | /* program tuner */ | 95 | /* program tuner */ |
101 | if (fe->ops.tuner_ops.set_params) | 96 | if (fe->ops.tuner_ops.set_params) |
102 | fe->ops.tuner_ops.set_params(fe); | 97 | fe->ops.tuner_ops.set_params(fe); |
diff --git a/drivers/media/usb/dvb-usb-v2/anysee.c b/drivers/media/usb/dvb-usb-v2/anysee.c index b430bcace0b8..6705d81f0cb2 100644 --- a/drivers/media/usb/dvb-usb-v2/anysee.c +++ b/drivers/media/usb/dvb-usb-v2/anysee.c | |||
@@ -874,7 +874,7 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) | |||
874 | 874 | ||
875 | /* attach demod */ | 875 | /* attach demod */ |
876 | adap->fe[0] = dvb_attach(cxd2820r_attach, | 876 | adap->fe[0] = dvb_attach(cxd2820r_attach, |
877 | &anysee_cxd2820r_config, &d->i2c_adap); | 877 | &anysee_cxd2820r_config, &d->i2c_adap, NULL); |
878 | 878 | ||
879 | state->has_ci = true; | 879 | state->has_ci = true; |
880 | 880 | ||
diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index a16531fa937a..34c5ea996031 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <media/videobuf-vmalloc.h> | 28 | #include <media/videobuf-vmalloc.h> |
29 | #include <media/tuner.h> | 29 | #include <media/tuner.h> |
30 | #include "tuner-simple.h" | 30 | #include "tuner-simple.h" |
31 | #include <linux/gpio.h> | ||
31 | 32 | ||
32 | #include "lgdt330x.h" | 33 | #include "lgdt330x.h" |
33 | #include "lgdt3305.h" | 34 | #include "lgdt3305.h" |
@@ -610,11 +611,6 @@ static struct tda10023_config em28xx_tda10023_config = { | |||
610 | static struct cxd2820r_config em28xx_cxd2820r_config = { | 611 | static struct cxd2820r_config em28xx_cxd2820r_config = { |
611 | .i2c_address = (0xd8 >> 1), | 612 | .i2c_address = (0xd8 >> 1), |
612 | .ts_mode = CXD2820R_TS_SERIAL, | 613 | .ts_mode = CXD2820R_TS_SERIAL, |
613 | |||
614 | /* enable LNA for DVB-T, DVB-T2 and DVB-C */ | ||
615 | .gpio_dvbt[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L, | ||
616 | .gpio_dvbt2[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L, | ||
617 | .gpio_dvbc[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L, | ||
618 | }; | 614 | }; |
619 | 615 | ||
620 | static struct tda18271_config em28xx_cxd2820r_tda18271_config = { | 616 | static struct tda18271_config em28xx_cxd2820r_tda18271_config = { |
@@ -813,7 +809,7 @@ static void em28xx_unregister_dvb(struct em28xx_dvb *dvb) | |||
813 | 809 | ||
814 | static int em28xx_dvb_init(struct em28xx *dev) | 810 | static int em28xx_dvb_init(struct em28xx *dev) |
815 | { | 811 | { |
816 | int result = 0, mfe_shared = 0; | 812 | int result = 0, mfe_shared = 0, gpio_chip_base; |
817 | struct em28xx_dvb *dvb; | 813 | struct em28xx_dvb *dvb; |
818 | 814 | ||
819 | if (!dev->board.has_dvb) { | 815 | if (!dev->board.has_dvb) { |
@@ -961,7 +957,8 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
961 | case EM28174_BOARD_PCTV_290E: | 957 | case EM28174_BOARD_PCTV_290E: |
962 | dvb->fe[0] = dvb_attach(cxd2820r_attach, | 958 | dvb->fe[0] = dvb_attach(cxd2820r_attach, |
963 | &em28xx_cxd2820r_config, | 959 | &em28xx_cxd2820r_config, |
964 | &dev->i2c_adap); | 960 | &dev->i2c_adap, |
961 | &gpio_chip_base); | ||
965 | if (dvb->fe[0]) { | 962 | if (dvb->fe[0]) { |
966 | /* FE 0 attach tuner */ | 963 | /* FE 0 attach tuner */ |
967 | if (!dvb_attach(tda18271_attach, | 964 | if (!dvb_attach(tda18271_attach, |
@@ -975,6 +972,16 @@ static int em28xx_dvb_init(struct em28xx *dev) | |||
975 | goto out_free; | 972 | goto out_free; |
976 | } | 973 | } |
977 | } | 974 | } |
975 | |||
976 | /* enable LNA for DVB-T, DVB-T2 and DVB-C */ | ||
977 | result = gpio_request_one(gpio_chip_base, GPIOF_INIT_LOW, | ||
978 | "LNA"); | ||
979 | if (result) | ||
980 | em28xx_errdev("gpio request failed %d\n", result); | ||
981 | else | ||
982 | gpio_free(gpio_chip_base); | ||
983 | |||
984 | result = 0; /* continue even set LNA fails */ | ||
978 | break; | 985 | break; |
979 | case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C: | 986 | case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C: |
980 | { | 987 | { |