aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManu Abraham <abraham.manu@gmail.com>2008-10-14 15:34:07 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-12-29 14:53:12 -0500
commitc59e7870fddbbc232221f92fb24958c605be404c (patch)
tree67474cdaba99d434be64122a4d5407c3b4ab0de4
parenta12ca6a6e143d77557772139f660121dfea6e923 (diff)
V4L/DVB (9344): DVB-Core update
Signed-off-by: Manu Abraham <manu@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c66
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h134
2 files changed, 192 insertions, 8 deletions
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 7a421e9dba5a..d006f042f22e 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -128,6 +128,7 @@ struct dvb_frontend_private {
128 unsigned int step_size; 128 unsigned int step_size;
129 int quality; 129 int quality;
130 unsigned int check_wrapped; 130 unsigned int check_wrapped;
131 enum dvbfe_search algo_status;
131}; 132};
132 133
133static void dvb_frontend_wakeup(struct dvb_frontend *fe); 134static void dvb_frontend_wakeup(struct dvb_frontend *fe);
@@ -516,6 +517,8 @@ static int dvb_frontend_thread(void *data)
516 struct dvb_frontend_private *fepriv = fe->frontend_priv; 517 struct dvb_frontend_private *fepriv = fe->frontend_priv;
517 unsigned long timeout; 518 unsigned long timeout;
518 fe_status_t s; 519 fe_status_t s;
520 enum dvbfe_algo algo;
521
519 struct dvb_frontend_parameters *params; 522 struct dvb_frontend_parameters *params;
520 523
521 dprintk("%s\n", __func__); 524 dprintk("%s\n", __func__);
@@ -562,23 +565,72 @@ restart:
562 565
563 /* do an iteration of the tuning loop */ 566 /* do an iteration of the tuning loop */
564 if (fe->ops.get_frontend_algo) { 567 if (fe->ops.get_frontend_algo) {
565 if (fe->ops.get_frontend_algo(fe) == FE_ALGO_HW) { 568 algo = fe->ops.get_frontend_algo(fe);
566 /* have we been asked to retune? */ 569 switch (algo) {
567 params = NULL; 570 case DVBFE_ALGO_HW:
571 dprintk("%s: Frontend ALGO = DVBFE_ALGO_HW\n", __func__);
572 params = NULL; /* have we been asked to RETUNE ? */
573
568 if (fepriv->state & FESTATE_RETUNE) { 574 if (fepriv->state & FESTATE_RETUNE) {
569 params = &fepriv->parameters; 575 dprintk("%s: Retune requested, FESTATE_RETUNE\n", __func__);
570 fepriv->state = FESTATE_TUNED; 576 fepriv->state = FESTATE_TUNED;
571 } 577 }
572 578
573 fe->ops.tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s); 579 if (fe->ops.tune)
580 fe->ops.tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s);
581
574 if (s != fepriv->status) { 582 if (s != fepriv->status) {
583 dprintk("%s: state changed, adding current state\n", __func__);
575 dvb_frontend_add_event(fe, s); 584 dvb_frontend_add_event(fe, s);
576 fepriv->status = s; 585 fepriv->status = s;
577 } 586 }
578 } else 587 break;
588 case DVBFE_ALGO_SW:
589 dprintk("%s: Frontend ALGO = DVBFE_ALGO_SW\n", __func__);
579 dvb_frontend_swzigzag(fe); 590 dvb_frontend_swzigzag(fe);
580 } else 591 break;
592 case DVBFE_ALGO_CUSTOM:
593 params = NULL; /* have we been asked to RETUNE ? */
594 dprintk("%s: Frontend ALGO = DVBFE_ALGO_CUSTOM, state=%d\n", __func__, fepriv->state);
595 if (fepriv->state & FESTATE_RETUNE) {
596 dprintk("%s: Retune requested, FESTAT_RETUNE\n", __func__);
597 fepriv->state = FESTATE_TUNED;
598 }
599 /* Case where we are going to search for a carrier
600 * User asked us to retune again for some reason, possibly
601 * requesting a search with a new set of parameters
602 */
603 if (fepriv->algo_status & DVBFE_ALGO_SEARCH_AGAIN) {
604 if (fe->ops.search)
605 fepriv->algo_status = fe->ops.search(fe, &fepriv->parameters);
606 /* We did do a search as was requested, the flags are
607 * now unset as well and has the flags wrt to search.
608 */
609
610 fepriv->algo_status &= ~DVBFE_ALGO_SEARCH_AGAIN;
611 }
612 /* Track the carrier if the search was successful */
613 if (fepriv->algo_status == DVBFE_ALGO_SEARCH_SUCCESS) {
614 if (fepriv->algo_status & DVBFE_ALGO_SEARCH_SUCCESS)
615 dprintk("%s: status = DVBFE_ALGO_SEARCH_SUCCESS\n", __func__);
616 if (fepriv->algo_status & DVBFE_ALGO_SEARCH_FAILED)
617 fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN;
618
619 fe->ops.read_status(fe, &s);
620 dvb_frontend_add_event(fe, s); /* update event list */
621 fepriv->status = s;
622 if (fe->ops.track)
623 fe->ops.track(fe, &fepriv->parameters);
624
625 }
626 break;
627 default:
628 dprintk("%s: UNDEFINED ALGO !\n", __func__);
629 break;
630 }
631 } else {
581 dvb_frontend_swzigzag(fe); 632 dvb_frontend_swzigzag(fe);
633 }
582 } 634 }
583 635
584 if (dvb_powerdown_on_sleep) { 636 if (dvb_powerdown_on_sleep) {
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index db4a63b0a32e..e176da472d7a 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -69,6 +69,125 @@ struct analog_parameters {
69 u64 std; 69 u64 std;
70}; 70};
71 71
72enum dvbfe_modcod {
73 DVBFE_MODCOD_DUMMY_PLFRAME = 0,
74 DVBFE_MODCOD_QPSK_1_4,
75 DVBFE_MODCOD_QPSK_1_3,
76 DVBFE_MODCOD_QPSK_2_5,
77 DVBFE_MODCOD_QPSK_1_2,
78 DVBFE_MODCOD_QPSK_3_5,
79 DVBFE_MODCOD_QPSK_2_3,
80 DVBFE_MODCOD_QPSK_3_4,
81 DVBFE_MODCOD_QPSK_4_5,
82 DVBFE_MODCOD_QPSK_5_6,
83 DVBFE_MODCOD_QPSK_8_9,
84 DVBFE_MODCOD_QPSK_9_10,
85 DVBFE_MODCOD_8PSK_3_5,
86 DVBFE_MODCOD_8PSK_2_3,
87 DVBFE_MODCOD_8PSK_3_4,
88 DVBFE_MODCOD_8PSK_5_6,
89 DVBFE_MODCOD_8PSK_8_9,
90 DVBFE_MODCOD_8PSK_9_10,
91 DVBFE_MODCOD_16APSK_2_3,
92 DVBFE_MODCOD_16APSK_3_4,
93 DVBFE_MODCOD_16APSK_4_5,
94 DVBFE_MODCOD_16APSK_5_6,
95 DVBFE_MODCOD_16APSK_8_9,
96 DVBFE_MODCOD_16APSK_9_10,
97 DVBFE_MODCOD_32APSK_3_4,
98 DVBFE_MODCOD_32APSK_4_5,
99 DVBFE_MODCOD_32APSK_5_6,
100 DVBFE_MODCOD_32APSK_8_9,
101 DVBFE_MODCOD_32APSK_9_10,
102 DVBFE_MODCOD_RESERVED_1,
103 DVBFE_MODCOD_BPSK_1_3,
104 DVBFE_MODCOD_BPSK_1_4,
105 DVBFE_MODCOD_RESERVED_2
106};
107
108enum tuner_param {
109 DVBFE_TUNER_FREQUENCY = (1 << 0),
110 DVBFE_TUNER_TUNERSTEP = (1 << 1),
111 DVBFE_TUNER_IFFREQ = (1 << 2),
112 DVBFE_TUNER_BANDWIDTH = (1 << 3),
113 DVBFE_TUNER_REFCLOCK = (1 << 4),
114 DVBFE_TUNER_IQSENSE = (1 << 5),
115 DVBFE_TUNER_DUMMY = (1 << 31)
116};
117
118/*
119 * ALGO_HW: (Hardware Algorithm)
120 * ----------------------------------------------------------------
121 * Devices that support this algorithm do everything in hardware
122 * and no software support is needed to handle them.
123 * Requesting these devices to LOCK is the only thing required,
124 * device is supposed to do everything in the hardware.
125 *
126 * ALGO_SW: (Software Algorithm)
127 * ----------------------------------------------------------------
128 * These are dumb devices, that require software to do everything
129 *
130 * ALGO_CUSTOM: (Customizable Agorithm)
131 * ----------------------------------------------------------------
132 * Devices having this algorithm can be customized to have specific
133 * algorithms in the frontend driver, rather than simply doing a
134 * software zig-zag. In this case the zigzag maybe hardware assisted
135 * or it maybe completely done in hardware. In all cases, usage of
136 * this algorithm, in conjunction with the search and track
137 * callbacks, utilizes the driver specific algorithm.
138 *
139 * ALGO_RECOVERY: (Recovery Algorithm)
140 * ----------------------------------------------------------------
141 * These devices have AUTO recovery capabilities from LOCK failure
142 */
143enum dvbfe_algo {
144 DVBFE_ALGO_HW = (1 << 0),
145 DVBFE_ALGO_SW = (1 << 1),
146 DVBFE_ALGO_CUSTOM = (1 << 2),
147 DVBFE_ALGO_RECOVERY = (1 << 31)
148};
149
150struct tuner_state {
151 u32 frequency;
152 u32 tunerstep;
153 u32 ifreq;
154 u32 bandwidth;
155 u32 iqsense;
156 u32 refclock;
157};
158
159/*
160 * search callback possible return status
161 *
162 * DVBFE_ALGO_SEARCH_SUCCESS
163 * The frontend search algorithm completed and returned succesfully
164 *
165 * DVBFE_ALGO_SEARCH_ASLEEP
166 * The frontend search algorithm is sleeping
167 *
168 * DVBFE_ALGO_SEARCH_FAILED
169 * The frontend search for a signal failed
170 *
171 * DVBFE_ALGO_SEARCH_INVALID
172 * The frontend search algorith was probably supplied with invalid
173 * parameters and the search is an invalid one
174 *
175 * DVBFE_ALGO_SEARCH_ERROR
176 * The frontend search algorithm failed due to some error
177 *
178 * DVBFE_ALGO_SEARCH_AGAIN
179 * The frontend search algorithm was requested to search again
180 */
181enum dvbfe_search {
182 DVBFE_ALGO_SEARCH_SUCCESS = (1 << 0),
183 DVBFE_ALGO_SEARCH_ASLEEP = (1 << 1),
184 DVBFE_ALGO_SEARCH_FAILED = (1 << 2),
185 DVBFE_ALGO_SEARCH_INVALID = (1 << 3),
186 DVBFE_ALGO_SEARCH_AGAIN = (1 << 4),
187 DVBFE_ALGO_SEARCH_ERROR = (1 << 31),
188};
189
190
72struct dvb_tuner_ops { 191struct dvb_tuner_ops {
73 192
74 struct dvb_tuner_info info; 193 struct dvb_tuner_info info;
@@ -99,6 +218,13 @@ struct dvb_tuner_ops {
99 * tuners which require sophisticated tuning loops, controlling each parameter seperately. */ 218 * tuners which require sophisticated tuning loops, controlling each parameter seperately. */
100 int (*set_frequency)(struct dvb_frontend *fe, u32 frequency); 219 int (*set_frequency)(struct dvb_frontend *fe, u32 frequency);
101 int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth); 220 int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth);
221
222 /*
223 * These are provided seperately from set_params in order to facilitate silicon
224 * tuners which require sophisticated tuning loops, controlling each parameter seperately.
225 */
226 int (*set_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state);
227 int (*get_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state);
102}; 228};
103 229
104struct analog_demod_info { 230struct analog_demod_info {
@@ -142,7 +268,7 @@ struct dvb_frontend_ops {
142 unsigned int *delay, 268 unsigned int *delay,
143 fe_status_t *status); 269 fe_status_t *status);
144 /* get frontend tuning algorithm from the module */ 270 /* get frontend tuning algorithm from the module */
145 int (*get_frontend_algo)(struct dvb_frontend *fe); 271 enum dvbfe_algo (*get_frontend_algo)(struct dvb_frontend *fe);
146 272
147 /* these two are only used for the swzigzag code */ 273 /* these two are only used for the swzigzag code */
148 int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); 274 int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
@@ -167,6 +293,12 @@ struct dvb_frontend_ops {
167 int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable); 293 int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable);
168 int (*ts_bus_ctrl)(struct dvb_frontend* fe, int acquire); 294 int (*ts_bus_ctrl)(struct dvb_frontend* fe, int acquire);
169 295
296 /* These callbacks are for devices that implement their own
297 * tuning algorithms, rather than a simple swzigzag
298 */
299 enum dvbfe_search (*search)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p);
300 int (*track)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p);
301
170 struct dvb_tuner_ops tuner_ops; 302 struct dvb_tuner_ops tuner_ops;
171 struct analog_demod_ops analog_ops; 303 struct analog_demod_ops analog_ops;
172 304