aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntti Palosaari <crope@iki.fi>2012-07-19 20:10:36 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-09-27 13:33:58 -0400
commit1e8f31f31726148c27de1ff4692c76c9bcff9860 (patch)
treeb593d16c49ae28aec06f8e3d42ca8b70d08a7ea6
parent75aeafc9d0e21222b876990946ef534b384462f1 (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.h14
-rw-r--r--drivers/media/dvb-frontends/cxd2820r_c.c5
-rw-r--r--drivers/media/dvb-frontends/cxd2820r_core.c108
-rw-r--r--drivers/media/dvb-frontends/cxd2820r_priv.h9
-rw-r--r--drivers/media/dvb-frontends/cxd2820r_t.c5
-rw-r--r--drivers/media/dvb-frontends/cxd2820r_t2.c5
-rw-r--r--drivers/media/usb/dvb-usb-v2/anysee.c2
-rw-r--r--drivers/media/usb/em28xx/em28xx-dvb.c21
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))
78extern struct dvb_frontend *cxd2820r_attach( 70extern 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
83static inline struct dvb_frontend *cxd2820r_attach( 76static 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
171int cxd2820r_gpio(struct dvb_frontend *fe) 171int 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)
582static void cxd2820r_release(struct dvb_frontend *fe) 567static 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
598static 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
613static 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
629static 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
602static const struct dvb_frontend_ops cxd2820r_ops = { 640static 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
647struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg, 685struct 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;
670error: 737error:
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
30struct reg_val_mask { 31struct 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
52extern int cxd2820r_debug; 57extern int cxd2820r_debug;
53 58
54int cxd2820r_gpio(struct dvb_frontend *fe); 59int cxd2820r_gpio(struct dvb_frontend *fe, u8 *gpio);
55 60
56int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val, 61int 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 = {
610static struct cxd2820r_config em28xx_cxd2820r_config = { 611static 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
620static struct tda18271_config em28xx_cxd2820r_tda18271_config = { 616static struct tda18271_config em28xx_cxd2820r_tda18271_config = {
@@ -813,7 +809,7 @@ static void em28xx_unregister_dvb(struct em28xx_dvb *dvb)
813 809
814static int em28xx_dvb_init(struct em28xx *dev) 810static 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 {