aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends/au8522_dig.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/frontends/au8522_dig.c')
-rw-r--r--drivers/media/dvb/frontends/au8522_dig.c215
1 files changed, 0 insertions, 215 deletions
diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c
index 25f650934c73..5fc70d6cd04f 100644
--- a/drivers/media/dvb/frontends/au8522_dig.c
+++ b/drivers/media/dvb/frontends/au8522_dig.c
@@ -30,74 +30,11 @@
30 30
31static int debug; 31static int debug;
32 32
33/* Despite the name "hybrid_tuner", the framework works just as well for
34 hybrid demodulators as well... */
35static LIST_HEAD(hybrid_tuner_instance_list);
36static DEFINE_MUTEX(au8522_list_mutex);
37
38#define dprintk(arg...)\ 33#define dprintk(arg...)\
39 do { if (debug)\ 34 do { if (debug)\
40 printk(arg);\ 35 printk(arg);\
41 } while (0) 36 } while (0)
42 37
43/* 16 bit registers, 8 bit values */
44int au8522_writereg(struct au8522_state *state, u16 reg, u8 data)
45{
46 int ret;
47 u8 buf[] = { (reg >> 8) | 0x80, reg & 0xff, data };
48
49 struct i2c_msg msg = { .addr = state->config->demod_address,
50 .flags = 0, .buf = buf, .len = 3 };
51
52 ret = i2c_transfer(state->i2c, &msg, 1);
53
54 if (ret != 1)
55 printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, "
56 "ret == %i)\n", __func__, reg, data, ret);
57
58 return (ret != 1) ? -1 : 0;
59}
60
61u8 au8522_readreg(struct au8522_state *state, u16 reg)
62{
63 int ret;
64 u8 b0[] = { (reg >> 8) | 0x40, reg & 0xff };
65 u8 b1[] = { 0 };
66
67 struct i2c_msg msg[] = {
68 { .addr = state->config->demod_address, .flags = 0,
69 .buf = b0, .len = 2 },
70 { .addr = state->config->demod_address, .flags = I2C_M_RD,
71 .buf = b1, .len = 1 } };
72
73 ret = i2c_transfer(state->i2c, msg, 2);
74
75 if (ret != 2)
76 printk(KERN_ERR "%s: readreg error (ret == %i)\n",
77 __func__, ret);
78 return b1[0];
79}
80
81static int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
82{
83 struct au8522_state *state = fe->demodulator_priv;
84
85 dprintk("%s(%d)\n", __func__, enable);
86
87 if (state->operational_mode == AU8522_ANALOG_MODE) {
88 /* We're being asked to manage the gate even though we're
89 not in digital mode. This can occur if we get switched
90 over to analog mode before the dvb_frontend kernel thread
91 has completely shutdown */
92 return 0;
93 }
94
95 if (enable)
96 return au8522_writereg(state, 0x106, 1);
97 else
98 return au8522_writereg(state, 0x106, 0);
99}
100
101struct mse2snr_tab { 38struct mse2snr_tab {
102 u16 val; 39 u16 val;
103 u16 data; 40 u16 data;
@@ -609,136 +546,6 @@ static int au8522_set_frontend(struct dvb_frontend *fe)
609 return 0; 546 return 0;
610} 547}
611 548
612/* Reset the demod hardware and reset all of the configuration registers
613 to a default state. */
614int au8522_init(struct dvb_frontend *fe)
615{
616 struct au8522_state *state = fe->demodulator_priv;
617 dprintk("%s()\n", __func__);
618
619 state->operational_mode = AU8522_DIGITAL_MODE;
620
621 /* Clear out any state associated with the digital side of the
622 chip, so that when it gets powered back up it won't think
623 that it is already tuned */
624 state->current_frequency = 0;
625
626 au8522_writereg(state, 0xa4, 1 << 5);
627
628 au8522_i2c_gate_ctrl(fe, 1);
629
630 return 0;
631}
632
633static int au8522_led_gpio_enable(struct au8522_state *state, int onoff)
634{
635 struct au8522_led_config *led_config = state->config->led_cfg;
636 u8 val;
637
638 /* bail out if we can't control an LED */
639 if (!led_config || !led_config->gpio_output ||
640 !led_config->gpio_output_enable || !led_config->gpio_output_disable)
641 return 0;
642
643 val = au8522_readreg(state, 0x4000 |
644 (led_config->gpio_output & ~0xc000));
645 if (onoff) {
646 /* enable GPIO output */
647 val &= ~((led_config->gpio_output_enable >> 8) & 0xff);
648 val |= (led_config->gpio_output_enable & 0xff);
649 } else {
650 /* disable GPIO output */
651 val &= ~((led_config->gpio_output_disable >> 8) & 0xff);
652 val |= (led_config->gpio_output_disable & 0xff);
653 }
654 return au8522_writereg(state, 0x8000 |
655 (led_config->gpio_output & ~0xc000), val);
656}
657
658/* led = 0 | off
659 * led = 1 | signal ok
660 * led = 2 | signal strong
661 * led < 0 | only light led if leds are currently off
662 */
663static int au8522_led_ctrl(struct au8522_state *state, int led)
664{
665 struct au8522_led_config *led_config = state->config->led_cfg;
666 int i, ret = 0;
667
668 /* bail out if we can't control an LED */
669 if (!led_config || !led_config->gpio_leds ||
670 !led_config->num_led_states || !led_config->led_states)
671 return 0;
672
673 if (led < 0) {
674 /* if LED is already lit, then leave it as-is */
675 if (state->led_state)
676 return 0;
677 else
678 led *= -1;
679 }
680
681 /* toggle LED if changing state */
682 if (state->led_state != led) {
683 u8 val;
684
685 dprintk("%s: %d\n", __func__, led);
686
687 au8522_led_gpio_enable(state, 1);
688
689 val = au8522_readreg(state, 0x4000 |
690 (led_config->gpio_leds & ~0xc000));
691
692 /* start with all leds off */
693 for (i = 0; i < led_config->num_led_states; i++)
694 val &= ~led_config->led_states[i];
695
696 /* set selected LED state */
697 if (led < led_config->num_led_states)
698 val |= led_config->led_states[led];
699 else if (led_config->num_led_states)
700 val |=
701 led_config->led_states[led_config->num_led_states - 1];
702
703 ret = au8522_writereg(state, 0x8000 |
704 (led_config->gpio_leds & ~0xc000), val);
705 if (ret < 0)
706 return ret;
707
708 state->led_state = led;
709
710 if (led == 0)
711 au8522_led_gpio_enable(state, 0);
712 }
713
714 return 0;
715}
716
717int au8522_sleep(struct dvb_frontend *fe)
718{
719 struct au8522_state *state = fe->demodulator_priv;
720 dprintk("%s()\n", __func__);
721
722 /* Only power down if the digital side is currently using the chip */
723 if (state->operational_mode == AU8522_ANALOG_MODE) {
724 /* We're not in one of the expected power modes, which means
725 that the DVB thread is probably telling us to go to sleep
726 even though the analog frontend has already started using
727 the chip. So ignore the request */
728 return 0;
729 }
730
731 /* turn off led */
732 au8522_led_ctrl(state, 0);
733
734 /* Power down the chip */
735 au8522_writereg(state, 0xa4, 1 << 5);
736
737 state->current_frequency = 0;
738
739 return 0;
740}
741
742static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status) 549static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status)
743{ 550{
744 struct au8522_state *state = fe->demodulator_priv; 551 struct au8522_state *state = fe->demodulator_priv;
@@ -931,28 +738,6 @@ static int au8522_get_tune_settings(struct dvb_frontend *fe,
931 738
932static struct dvb_frontend_ops au8522_ops; 739static struct dvb_frontend_ops au8522_ops;
933 740
934int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c,
935 u8 client_address)
936{
937 int ret;
938
939 mutex_lock(&au8522_list_mutex);
940 ret = hybrid_tuner_request_state(struct au8522_state, (*state),
941 hybrid_tuner_instance_list,
942 i2c, client_address, "au8522");
943 mutex_unlock(&au8522_list_mutex);
944
945 return ret;
946}
947
948void au8522_release_state(struct au8522_state *state)
949{
950 mutex_lock(&au8522_list_mutex);
951 if (state != NULL)
952 hybrid_tuner_release_state(state);
953 mutex_unlock(&au8522_list_mutex);
954}
955
956 741
957static void au8522_release(struct dvb_frontend *fe) 742static void au8522_release(struct dvb_frontend *fe)
958{ 743{