diff options
author | Manu Abraham <abraham.manu@gmail.com> | 2008-10-14 15:34:07 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-12-29 14:53:12 -0500 |
commit | c59e7870fddbbc232221f92fb24958c605be404c (patch) | |
tree | 67474cdaba99d434be64122a4d5407c3b4ab0de4 | |
parent | a12ca6a6e143d77557772139f660121dfea6e923 (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.c | 66 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_frontend.h | 134 |
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 | ||
133 | static void dvb_frontend_wakeup(struct dvb_frontend *fe); | 134 | static 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 | ||
72 | enum 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 | |||
108 | enum 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 | */ | ||
143 | enum 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 | |||
150 | struct 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 | */ | ||
181 | enum 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 | |||
72 | struct dvb_tuner_ops { | 191 | struct 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 | ||
104 | struct analog_demod_info { | 230 | struct 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 | ||