aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends/cx24123.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/frontends/cx24123.c')
-rw-r--r--drivers/media/dvb/frontends/cx24123.c195
1 files changed, 51 insertions, 144 deletions
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c
index 691dc840dcc0..f2f795cba56a 100644
--- a/drivers/media/dvb/frontends/cx24123.c
+++ b/drivers/media/dvb/frontends/cx24123.c
@@ -41,14 +41,12 @@ static int debug;
41struct cx24123_state 41struct cx24123_state
42{ 42{
43 struct i2c_adapter* i2c; 43 struct i2c_adapter* i2c;
44 struct dvb_frontend_ops ops;
45 const struct cx24123_config* config; 44 const struct cx24123_config* config;
46 45
47 struct dvb_frontend frontend; 46 struct dvb_frontend frontend;
48 47
49 u32 lastber; 48 u32 lastber;
50 u16 snr; 49 u16 snr;
51 u8 lnbreg;
52 50
53 /* Some PLL specifics for tuning */ 51 /* Some PLL specifics for tuning */
54 u32 VCAarg; 52 u32 VCAarg;
@@ -249,29 +247,6 @@ static int cx24123_writereg(struct cx24123_state* state, int reg, int data)
249 return 0; 247 return 0;
250} 248}
251 249
252static int cx24123_writelnbreg(struct cx24123_state* state, int reg, int data)
253{
254 u8 buf[] = { reg, data };
255 /* fixme: put the intersil addr int the config */
256 struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 2 };
257 int err;
258
259 if (debug>1)
260 printk("cx24123: %s: writeln addr=0x08, reg 0x%02x, value 0x%02x\n",
261 __FUNCTION__,reg, data);
262
263 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
264 printk("%s: writelnbreg error (err == %i, reg == 0x%02x,"
265 " data == 0x%02x)\n", __FUNCTION__, err, reg, data);
266 return -EREMOTEIO;
267 }
268
269 /* cache the write, no way to read back */
270 state->lnbreg = data;
271
272 return 0;
273}
274
275static int cx24123_readreg(struct cx24123_state* state, u8 reg) 250static int cx24123_readreg(struct cx24123_state* state, u8 reg)
276{ 251{
277 int ret; 252 int ret;
@@ -295,11 +270,6 @@ static int cx24123_readreg(struct cx24123_state* state, u8 reg)
295 return b1[0]; 270 return b1[0];
296} 271}
297 272
298static int cx24123_readlnbreg(struct cx24123_state* state, u8 reg)
299{
300 return state->lnbreg;
301}
302
303static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion) 273static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion)
304{ 274{
305 u8 nom_reg = cx24123_readreg(state, 0x0e); 275 u8 nom_reg = cx24123_readreg(state, 0x0e);
@@ -458,8 +428,8 @@ static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate)
458 u8 pll_mult; 428 u8 pll_mult;
459 429
460 /* check if symbol rate is within limits */ 430 /* check if symbol rate is within limits */
461 if ((srate > state->ops.info.symbol_rate_max) || 431 if ((srate > state->frontend.ops.info.symbol_rate_max) ||
462 (srate < state->ops.info.symbol_rate_min)) 432 (srate < state->frontend.ops.info.symbol_rate_min))
463 return -EOPNOTSUPP;; 433 return -EOPNOTSUPP;;
464 434
465 /* choose the sampling rate high enough for the required operation, 435 /* choose the sampling rate high enough for the required operation,
@@ -687,13 +657,6 @@ static int cx24123_initfe(struct dvb_frontend* fe)
687 for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++) 657 for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++)
688 cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data); 658 cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data);
689 659
690 if (state->config->pll_init)
691 state->config->pll_init(fe);
692
693 /* Configure the LNB for 14V */
694 if (state->config->use_isl6421)
695 cx24123_writelnbreg(state, 0x0, 0x2a);
696
697 return 0; 660 return 0;
698} 661}
699 662
@@ -702,50 +665,18 @@ static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage
702 struct cx24123_state *state = fe->demodulator_priv; 665 struct cx24123_state *state = fe->demodulator_priv;
703 u8 val; 666 u8 val;
704 667
705 switch (state->config->use_isl6421) { 668 val = cx24123_readreg(state, 0x29) & ~0x40;
706
707 case 1:
708 669
709 val = cx24123_readlnbreg(state, 0x0); 670 switch (voltage) {
710 671 case SEC_VOLTAGE_13:
711 switch (voltage) { 672 dprintk("%s: setting voltage 13V\n", __FUNCTION__);
712 case SEC_VOLTAGE_13: 673 return cx24123_writereg(state, 0x29, val | 0x80);
713 dprintk("%s: isl6421 voltage = 13V\n",__FUNCTION__); 674 case SEC_VOLTAGE_18:
714 return cx24123_writelnbreg(state, 0x0, val & 0x32); /* V 13v */ 675 dprintk("%s: setting voltage 18V\n", __FUNCTION__);
715 case SEC_VOLTAGE_18: 676 return cx24123_writereg(state, 0x29, val & 0x7f);
716 dprintk("%s: isl6421 voltage = 18V\n",__FUNCTION__); 677 default:
717 return cx24123_writelnbreg(state, 0x0, val | 0x04); /* H 18v */ 678 return -EINVAL;
718 case SEC_VOLTAGE_OFF: 679 };
719 dprintk("%s: isl5421 voltage off\n",__FUNCTION__);
720 return cx24123_writelnbreg(state, 0x0, val & 0x30);
721 default:
722 return -EINVAL;
723 };
724
725 case 0:
726
727 val = cx24123_readreg(state, 0x29);
728
729 switch (voltage) {
730 case SEC_VOLTAGE_13:
731 dprintk("%s: setting voltage 13V\n", __FUNCTION__);
732 if (state->config->enable_lnb_voltage)
733 state->config->enable_lnb_voltage(fe, 1);
734 return cx24123_writereg(state, 0x29, val | 0x80);
735 case SEC_VOLTAGE_18:
736 dprintk("%s: setting voltage 18V\n", __FUNCTION__);
737 if (state->config->enable_lnb_voltage)
738 state->config->enable_lnb_voltage(fe, 1);
739 return cx24123_writereg(state, 0x29, val & 0x7f);
740 case SEC_VOLTAGE_OFF:
741 dprintk("%s: setting voltage off\n", __FUNCTION__);
742 if (state->config->enable_lnb_voltage)
743 state->config->enable_lnb_voltage(fe, 0);
744 return 0;
745 default:
746 return -EINVAL;
747 };
748 }
749 680
750 return 0; 681 return 0;
751} 682}
@@ -766,27 +697,20 @@ static void cx24123_wait_for_diseqc(struct cx24123_state *state)
766static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd) 697static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
767{ 698{
768 struct cx24123_state *state = fe->demodulator_priv; 699 struct cx24123_state *state = fe->demodulator_priv;
769 int i, val; 700 int i, val, tone;
770 701
771 dprintk("%s:\n",__FUNCTION__); 702 dprintk("%s:\n",__FUNCTION__);
772 703
773 /* check if continuous tone has been stopped */ 704 /* stop continuous tone if enabled */
774 if (state->config->use_isl6421) 705 tone = cx24123_readreg(state, 0x29);
775 val = cx24123_readlnbreg(state, 0x00) & 0x10; 706 if (tone & 0x10)
776 else 707 cx24123_writereg(state, 0x29, tone & ~0x50);
777 val = cx24123_readreg(state, 0x29) & 0x10;
778
779
780 if (val) {
781 printk("%s: ERROR: attempt to send diseqc command before tone is off\n", __FUNCTION__);
782 return -ENOTSUPP;
783 }
784 708
785 /* wait for diseqc queue ready */ 709 /* wait for diseqc queue ready */
786 cx24123_wait_for_diseqc(state); 710 cx24123_wait_for_diseqc(state);
787 711
788 /* select tone mode */ 712 /* select tone mode */
789 cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xf8); 713 cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb);
790 714
791 for (i = 0; i < cmd->msg_len; i++) 715 for (i = 0; i < cmd->msg_len; i++)
792 cx24123_writereg(state, 0x2C + i, cmd->msg[i]); 716 cx24123_writereg(state, 0x2C + i, cmd->msg[i]);
@@ -797,36 +721,33 @@ static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma
797 /* wait for diseqc message to finish sending */ 721 /* wait for diseqc message to finish sending */
798 cx24123_wait_for_diseqc(state); 722 cx24123_wait_for_diseqc(state);
799 723
724 /* restart continuous tone if enabled */
725 if (tone & 0x10) {
726 cx24123_writereg(state, 0x29, tone & ~0x40);
727 }
728
800 return 0; 729 return 0;
801} 730}
802 731
803static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) 732static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
804{ 733{
805 struct cx24123_state *state = fe->demodulator_priv; 734 struct cx24123_state *state = fe->demodulator_priv;
806 int val; 735 int val, tone;
807 736
808 dprintk("%s:\n", __FUNCTION__); 737 dprintk("%s:\n", __FUNCTION__);
809 738
810 /* check if continuous tone has been stoped */ 739 /* stop continuous tone if enabled */
811 if (state->config->use_isl6421) 740 tone = cx24123_readreg(state, 0x29);
812 val = cx24123_readlnbreg(state, 0x00) & 0x10; 741 if (tone & 0x10)
813 else 742 cx24123_writereg(state, 0x29, tone & ~0x50);
814 val = cx24123_readreg(state, 0x29) & 0x10;
815
816
817 if (val) {
818 printk("%s: ERROR: attempt to send diseqc command before tone is off\n", __FUNCTION__);
819 return -ENOTSUPP;
820 }
821 743
744 /* wait for diseqc queue ready */
822 cx24123_wait_for_diseqc(state); 745 cx24123_wait_for_diseqc(state);
823 746
824 /* select tone mode */ 747 /* select tone mode */
825 val = cx24123_readreg(state, 0x2a) & 0xf8; 748 cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) | 0x4);
826 cx24123_writereg(state, 0x2a, val | 0x04); 749 msleep(30);
827
828 val = cx24123_readreg(state, 0x29); 750 val = cx24123_readreg(state, 0x29);
829
830 if (burst == SEC_MINI_A) 751 if (burst == SEC_MINI_A)
831 cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x00)); 752 cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x00));
832 else if (burst == SEC_MINI_B) 753 else if (burst == SEC_MINI_B)
@@ -835,7 +756,12 @@ static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t
835 return -EINVAL; 756 return -EINVAL;
836 757
837 cx24123_wait_for_diseqc(state); 758 cx24123_wait_for_diseqc(state);
759 cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb);
838 760
761 /* restart continuous tone if enabled */
762 if (tone & 0x10) {
763 cx24123_writereg(state, 0x29, tone & ~0x40);
764 }
839 return 0; 765 return 0;
840} 766}
841 767
@@ -976,38 +902,21 @@ static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
976 struct cx24123_state *state = fe->demodulator_priv; 902 struct cx24123_state *state = fe->demodulator_priv;
977 u8 val; 903 u8 val;
978 904
979 switch (state->config->use_isl6421) { 905 /* wait for diseqc queue ready */
980 case 1: 906 cx24123_wait_for_diseqc(state);
981
982 val = cx24123_readlnbreg(state, 0x0);
983
984 switch (tone) {
985 case SEC_TONE_ON:
986 dprintk("%s: isl6421 sec tone on\n",__FUNCTION__);
987 return cx24123_writelnbreg(state, 0x0, val | 0x10);
988 case SEC_TONE_OFF:
989 dprintk("%s: isl6421 sec tone off\n",__FUNCTION__);
990 return cx24123_writelnbreg(state, 0x0, val & 0x2f);
991 default:
992 printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone);
993 return -EINVAL;
994 }
995
996 case 0:
997 907
998 val = cx24123_readreg(state, 0x29); 908 val = cx24123_readreg(state, 0x29) & ~0x40;
999 909
1000 switch (tone) { 910 switch (tone) {
1001 case SEC_TONE_ON: 911 case SEC_TONE_ON:
1002 dprintk("%s: setting tone on\n", __FUNCTION__); 912 dprintk("%s: setting tone on\n", __FUNCTION__);
1003 return cx24123_writereg(state, 0x29, val | 0x10); 913 return cx24123_writereg(state, 0x29, val | 0x10);
1004 case SEC_TONE_OFF: 914 case SEC_TONE_OFF:
1005 dprintk("%s: setting tone off\n",__FUNCTION__); 915 dprintk("%s: setting tone off\n",__FUNCTION__);
1006 return cx24123_writereg(state, 0x29, val & 0xef); 916 return cx24123_writereg(state, 0x29, val & 0xef);
1007 default: 917 default:
1008 printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone); 918 printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone);
1009 return -EINVAL; 919 return -EINVAL;
1010 }
1011 } 920 }
1012 921
1013 return 0; 922 return 0;
@@ -1040,10 +949,8 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
1040 /* setup the state */ 949 /* setup the state */
1041 state->config = config; 950 state->config = config;
1042 state->i2c = i2c; 951 state->i2c = i2c;
1043 memcpy(&state->ops, &cx24123_ops, sizeof(struct dvb_frontend_ops));
1044 state->lastber = 0; 952 state->lastber = 0;
1045 state->snr = 0; 953 state->snr = 0;
1046 state->lnbreg = 0;
1047 state->VCAarg = 0; 954 state->VCAarg = 0;
1048 state->VGAarg = 0; 955 state->VGAarg = 0;
1049 state->bandselectarg = 0; 956 state->bandselectarg = 0;
@@ -1059,7 +966,7 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
1059 } 966 }
1060 967
1061 /* create dvb_frontend */ 968 /* create dvb_frontend */
1062 state->frontend.ops = &state->ops; 969 memcpy(&state->frontend.ops, &cx24123_ops, sizeof(struct dvb_frontend_ops));
1063 state->frontend.demodulator_priv = state; 970 state->frontend.demodulator_priv = state;
1064 return &state->frontend; 971 return &state->frontend;
1065 972