diff options
author | Mike Isely <isely@pobox.com> | 2008-03-28 04:38:54 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-04-24 13:09:47 -0400 |
commit | 1c9d10d4d2e791a9eacd9f919dec78c5bc6737e8 (patch) | |
tree | a63ebc17d527109d3ab65cecd04bc03166a4245b /drivers/media | |
parent | 448cb48e6e2fcd3a948cc549c5c6ab7f84440a54 (diff) |
V4L/DVB (7701): pvrusb2: Centralize handling of simple FX2 commands
Numerous places in the driver need to issue simple commands to the FX2
microcontroller (e.g. only 1 or 2 bytes, no reply needed). Previously
each place that did this, had to take lock, set up a central buffer,
and call the function to perform the handshake. This change puts
these steps into a single spot. This also has the effect of removing
the need to mess with the control lock from numerous places in the
code.
Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-hdw.c | 198 |
1 files changed, 116 insertions, 82 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index a26b5251ec1b..063aed0067cd 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c | |||
@@ -216,6 +216,39 @@ static const char *pvr2_state_names[] = { | |||
216 | }; | 216 | }; |
217 | 217 | ||
218 | 218 | ||
219 | struct pvr2_fx2cmd_desc { | ||
220 | unsigned char id; | ||
221 | unsigned char *desc; | ||
222 | }; | ||
223 | |||
224 | static const struct pvr2_fx2cmd_desc pvr2_fx2cmd_desc[] = { | ||
225 | {FX2CMD_MEM_WRITE_DWORD, "write encoder dword"}, | ||
226 | {FX2CMD_MEM_READ_DWORD, "read encoder dword"}, | ||
227 | {FX2CMD_MEM_READ_64BYTES, "read encoder 64bytes"}, | ||
228 | {FX2CMD_REG_WRITE, "write encoder register"}, | ||
229 | {FX2CMD_REG_READ, "read encoder register"}, | ||
230 | {FX2CMD_MEMSEL, "encoder memsel"}, | ||
231 | {FX2CMD_I2C_WRITE, "i2c write"}, | ||
232 | {FX2CMD_I2C_READ, "i2c read"}, | ||
233 | {FX2CMD_GET_USB_SPEED, "get USB speed"}, | ||
234 | {FX2CMD_STREAMING_ON, "stream on"}, | ||
235 | {FX2CMD_STREAMING_OFF, "stream off"}, | ||
236 | {FX2CMD_FWPOST1, "fwpost1"}, | ||
237 | {FX2CMD_POWER_OFF, "power off"}, | ||
238 | {FX2CMD_POWER_ON, "power on"}, | ||
239 | {FX2CMD_DEEP_RESET, "deep reset"}, | ||
240 | {FX2CMD_GET_EEPROM_ADDR, "get rom addr"}, | ||
241 | {FX2CMD_GET_IR_CODE, "get IR code"}, | ||
242 | {FX2CMD_HCW_DEMOD_RESETIN, "hcw demod resetin"}, | ||
243 | {FX2CMD_HCW_DTV_STREAMING_ON, "hcw dtv stream on"}, | ||
244 | {FX2CMD_HCW_DTV_STREAMING_OFF, "hcw dtv stream off"}, | ||
245 | {FX2CMD_ONAIR_DTV_STREAMING_ON, "onair dtv stream on"}, | ||
246 | {FX2CMD_ONAIR_DTV_STREAMING_OFF, "onair dtv stream off"}, | ||
247 | {FX2CMD_ONAIR_DTV_POWER_ON, "onair dtv power on"}, | ||
248 | {FX2CMD_ONAIR_DTV_POWER_OFF, "onair dtv power off"}, | ||
249 | }; | ||
250 | |||
251 | |||
219 | static void pvr2_hdw_state_sched(struct pvr2_hdw *); | 252 | static void pvr2_hdw_state_sched(struct pvr2_hdw *); |
220 | static int pvr2_hdw_state_eval(struct pvr2_hdw *); | 253 | static int pvr2_hdw_state_eval(struct pvr2_hdw *); |
221 | static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *,unsigned long); | 254 | static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *,unsigned long); |
@@ -231,6 +264,7 @@ static void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw); | |||
231 | static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw); | 264 | static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw); |
232 | static void pvr2_hdw_quiescent_timeout(unsigned long); | 265 | static void pvr2_hdw_quiescent_timeout(unsigned long); |
233 | static void pvr2_hdw_encoder_wait_timeout(unsigned long); | 266 | static void pvr2_hdw_encoder_wait_timeout(unsigned long); |
267 | static int pvr2_issue_simple_cmd(struct pvr2_hdw *,u32); | ||
234 | static int pvr2_send_request_ex(struct pvr2_hdw *hdw, | 268 | static int pvr2_send_request_ex(struct pvr2_hdw *hdw, |
235 | unsigned int timeout,int probe_fl, | 269 | unsigned int timeout,int probe_fl, |
236 | void *write_data,unsigned int write_len, | 270 | void *write_data,unsigned int write_len, |
@@ -1219,13 +1253,8 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) | |||
1219 | ret |= pvr2_write_register(hdw, 0xaa04, 0x00057810); /*unknown*/ | 1253 | ret |= pvr2_write_register(hdw, 0xaa04, 0x00057810); /*unknown*/ |
1220 | ret |= pvr2_write_register(hdw, 0xaa10, 0x00148500); /*unknown*/ | 1254 | ret |= pvr2_write_register(hdw, 0xaa10, 0x00148500); /*unknown*/ |
1221 | ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/ | 1255 | ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/ |
1222 | LOCK_TAKE(hdw->ctl_lock); do { | 1256 | ret |= pvr2_issue_simple_cmd(hdw,FX2CMD_FWPOST1); |
1223 | hdw->cmd_buffer[0] = FX2CMD_FWPOST1; | 1257 | ret |= pvr2_issue_simple_cmd(hdw,FX2CMD_MEMSEL | (1 << 8) | (0 << 16)); |
1224 | ret |= pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0); | ||
1225 | hdw->cmd_buffer[0] = FX2CMD_MEMSEL; | ||
1226 | hdw->cmd_buffer[1] = 0; | ||
1227 | ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,NULL,0); | ||
1228 | } while (0); LOCK_GIVE(hdw->ctl_lock); | ||
1229 | 1258 | ||
1230 | if (ret) { | 1259 | if (ret) { |
1231 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | 1260 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
@@ -1290,11 +1319,7 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) | |||
1290 | 1319 | ||
1291 | ret |= pvr2_write_register(hdw, 0x9054, 0xffffffff); /*reset hw blocks*/ | 1320 | ret |= pvr2_write_register(hdw, 0x9054, 0xffffffff); /*reset hw blocks*/ |
1292 | ret |= pvr2_write_register(hdw, 0x9058, 0xffffffe8); /*VPU ctrl*/ | 1321 | ret |= pvr2_write_register(hdw, 0x9058, 0xffffffe8); /*VPU ctrl*/ |
1293 | LOCK_TAKE(hdw->ctl_lock); do { | 1322 | ret |= pvr2_issue_simple_cmd(hdw,FX2CMD_MEMSEL | (1 << 8) | (0 << 16)); |
1294 | hdw->cmd_buffer[0] = FX2CMD_MEMSEL; | ||
1295 | hdw->cmd_buffer[1] = 0; | ||
1296 | ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,NULL,0); | ||
1297 | } while (0); LOCK_GIVE(hdw->ctl_lock); | ||
1298 | 1323 | ||
1299 | if (ret) { | 1324 | if (ret) { |
1300 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, | 1325 | pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
@@ -3093,6 +3118,67 @@ int pvr2_send_request(struct pvr2_hdw *hdw, | |||
3093 | read_data,read_len); | 3118 | read_data,read_len); |
3094 | } | 3119 | } |
3095 | 3120 | ||
3121 | |||
3122 | static int pvr2_issue_simple_cmd(struct pvr2_hdw *hdw,u32 cmdcode) | ||
3123 | { | ||
3124 | int ret; | ||
3125 | unsigned int cnt = 1; | ||
3126 | unsigned int args = 0; | ||
3127 | LOCK_TAKE(hdw->ctl_lock); | ||
3128 | hdw->cmd_buffer[0] = cmdcode & 0xffu; | ||
3129 | args = (cmdcode >> 8) & 0xffu; | ||
3130 | args = (args > 2) ? 2 : args; | ||
3131 | if (args) { | ||
3132 | cnt += args; | ||
3133 | hdw->cmd_buffer[1] = (cmdcode >> 16) & 0xffu; | ||
3134 | if (args > 1) { | ||
3135 | hdw->cmd_buffer[2] = (cmdcode >> 24) & 0xffu; | ||
3136 | } | ||
3137 | } | ||
3138 | if (pvrusb2_debug & PVR2_TRACE_INIT) { | ||
3139 | unsigned int idx; | ||
3140 | unsigned int ccnt,bcnt; | ||
3141 | char tbuf[50]; | ||
3142 | cmdcode &= 0xffu; | ||
3143 | bcnt = 0; | ||
3144 | ccnt = scnprintf(tbuf+bcnt, | ||
3145 | sizeof(tbuf)-bcnt, | ||
3146 | "Sending FX2 command 0x%x",cmdcode); | ||
3147 | bcnt += ccnt; | ||
3148 | for (idx = 0; idx < ARRAY_SIZE(pvr2_fx2cmd_desc); idx++) { | ||
3149 | if (pvr2_fx2cmd_desc[idx].id == cmdcode) { | ||
3150 | ccnt = scnprintf(tbuf+bcnt, | ||
3151 | sizeof(tbuf)-bcnt, | ||
3152 | " \"%s\"", | ||
3153 | pvr2_fx2cmd_desc[idx].desc); | ||
3154 | bcnt += ccnt; | ||
3155 | break; | ||
3156 | } | ||
3157 | } | ||
3158 | if (args) { | ||
3159 | ccnt = scnprintf(tbuf+bcnt, | ||
3160 | sizeof(tbuf)-bcnt, | ||
3161 | " (%u",hdw->cmd_buffer[1]); | ||
3162 | bcnt += ccnt; | ||
3163 | if (args > 1) { | ||
3164 | ccnt = scnprintf(tbuf+bcnt, | ||
3165 | sizeof(tbuf)-bcnt, | ||
3166 | ",%u",hdw->cmd_buffer[2]); | ||
3167 | bcnt += ccnt; | ||
3168 | } | ||
3169 | ccnt = scnprintf(tbuf+bcnt, | ||
3170 | sizeof(tbuf)-bcnt, | ||
3171 | ")"); | ||
3172 | bcnt += ccnt; | ||
3173 | } | ||
3174 | pvr2_trace(PVR2_TRACE_INIT,"%.*s",bcnt,tbuf); | ||
3175 | } | ||
3176 | ret = pvr2_send_request(hdw,hdw->cmd_buffer,cnt,NULL,0); | ||
3177 | LOCK_GIVE(hdw->ctl_lock); | ||
3178 | return ret; | ||
3179 | } | ||
3180 | |||
3181 | |||
3096 | int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data) | 3182 | int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data) |
3097 | { | 3183 | { |
3098 | int ret; | 3184 | int ret; |
@@ -3200,40 +3286,19 @@ void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val) | |||
3200 | 3286 | ||
3201 | int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw) | 3287 | int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw) |
3202 | { | 3288 | { |
3203 | int status; | 3289 | return pvr2_issue_simple_cmd(hdw,FX2CMD_DEEP_RESET); |
3204 | LOCK_TAKE(hdw->ctl_lock); do { | ||
3205 | pvr2_trace(PVR2_TRACE_INIT,"Requesting uproc hard reset"); | ||
3206 | hdw->cmd_buffer[0] = FX2CMD_DEEP_RESET; | ||
3207 | status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0); | ||
3208 | } while (0); LOCK_GIVE(hdw->ctl_lock); | ||
3209 | return status; | ||
3210 | } | 3290 | } |
3211 | 3291 | ||
3212 | 3292 | ||
3213 | static int pvr2_hdw_cmd_power_ctrl(struct pvr2_hdw *hdw, int onoff) | ||
3214 | { | ||
3215 | int status; | ||
3216 | LOCK_TAKE(hdw->ctl_lock); do { | ||
3217 | if (onoff) { | ||
3218 | pvr2_trace(PVR2_TRACE_INIT, "Requesting powerup"); | ||
3219 | hdw->cmd_buffer[0] = FX2CMD_POWER_ON; | ||
3220 | } else { | ||
3221 | pvr2_trace(PVR2_TRACE_INIT, "Requesting powerdown"); | ||
3222 | hdw->cmd_buffer[0] = FX2CMD_POWER_OFF; | ||
3223 | } | ||
3224 | status = pvr2_send_request(hdw, hdw->cmd_buffer, 1, NULL, 0); | ||
3225 | } while (0); LOCK_GIVE(hdw->ctl_lock); | ||
3226 | return status; | ||
3227 | } | ||
3228 | |||
3229 | int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw) | 3293 | int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw) |
3230 | { | 3294 | { |
3231 | return pvr2_hdw_cmd_power_ctrl(hdw, 1); | 3295 | return pvr2_issue_simple_cmd(hdw,FX2CMD_POWER_ON); |
3232 | } | 3296 | } |
3233 | 3297 | ||
3298 | |||
3234 | int pvr2_hdw_cmd_powerdown(struct pvr2_hdw *hdw) | 3299 | int pvr2_hdw_cmd_powerdown(struct pvr2_hdw *hdw) |
3235 | { | 3300 | { |
3236 | return pvr2_hdw_cmd_power_ctrl(hdw, 0); | 3301 | return pvr2_issue_simple_cmd(hdw,FX2CMD_POWER_OFF); |
3237 | } | 3302 | } |
3238 | 3303 | ||
3239 | 3304 | ||
@@ -3260,55 +3325,29 @@ int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw) | |||
3260 | 3325 | ||
3261 | static int pvr2_hdw_cmd_hcw_demod_reset(struct pvr2_hdw *hdw, int onoff) | 3326 | static int pvr2_hdw_cmd_hcw_demod_reset(struct pvr2_hdw *hdw, int onoff) |
3262 | { | 3327 | { |
3263 | int status; | 3328 | hdw->flag_ok = !0; |
3264 | 3329 | return pvr2_issue_simple_cmd(hdw, | |
3265 | LOCK_TAKE(hdw->ctl_lock); do { | 3330 | FX2CMD_HCW_DEMOD_RESETIN | |
3266 | pvr2_trace(PVR2_TRACE_INIT, | 3331 | (1 << 8) | |
3267 | "Issuing fe demod wake command (%s)", | 3332 | ((onoff ? 1 : 0) << 16)); |
3268 | (onoff ? "on" : "off")); | ||
3269 | hdw->flag_ok = !0; | ||
3270 | hdw->cmd_buffer[0] = FX2CMD_HCW_DEMOD_RESETIN; | ||
3271 | hdw->cmd_buffer[1] = onoff; | ||
3272 | status = pvr2_send_request(hdw, hdw->cmd_buffer, 2, NULL, 0); | ||
3273 | } while (0); LOCK_GIVE(hdw->ctl_lock); | ||
3274 | |||
3275 | return status; | ||
3276 | } | 3333 | } |
3277 | 3334 | ||
3278 | 3335 | ||
3279 | static int pvr2_hdw_cmd_onair_fe_power_ctrl(struct pvr2_hdw *hdw, int onoff) | 3336 | static int pvr2_hdw_cmd_onair_fe_power_ctrl(struct pvr2_hdw *hdw, int onoff) |
3280 | { | 3337 | { |
3281 | int status; | 3338 | hdw->flag_ok = !0; |
3282 | 3339 | return pvr2_issue_simple_cmd(hdw,(onoff ? | |
3283 | LOCK_TAKE(hdw->ctl_lock); do { | 3340 | FX2CMD_ONAIR_DTV_POWER_ON : |
3284 | pvr2_trace(PVR2_TRACE_INIT, | 3341 | FX2CMD_ONAIR_DTV_POWER_OFF)); |
3285 | "Issuing fe power command to CPLD (%s)", | ||
3286 | (onoff ? "on" : "off")); | ||
3287 | hdw->flag_ok = !0; | ||
3288 | hdw->cmd_buffer[0] = | ||
3289 | (onoff ? FX2CMD_ONAIR_DTV_POWER_ON : | ||
3290 | FX2CMD_ONAIR_DTV_POWER_OFF); | ||
3291 | status = pvr2_send_request(hdw, hdw->cmd_buffer, 1, NULL, 0); | ||
3292 | } while (0); LOCK_GIVE(hdw->ctl_lock); | ||
3293 | |||
3294 | return status; | ||
3295 | } | 3342 | } |
3296 | 3343 | ||
3297 | 3344 | ||
3298 | static int pvr2_hdw_cmd_onair_digital_path_ctrl(struct pvr2_hdw *hdw, | 3345 | static int pvr2_hdw_cmd_onair_digital_path_ctrl(struct pvr2_hdw *hdw, |
3299 | int onoff) | 3346 | int onoff) |
3300 | { | 3347 | { |
3301 | int status; | 3348 | return pvr2_issue_simple_cmd(hdw,(onoff ? |
3302 | LOCK_TAKE(hdw->ctl_lock); do { | 3349 | FX2CMD_ONAIR_DTV_STREAMING_ON : |
3303 | pvr2_trace(PVR2_TRACE_INIT, | 3350 | FX2CMD_ONAIR_DTV_STREAMING_OFF)); |
3304 | "Issuing onair digital setup command (%s)", | ||
3305 | (onoff ? "on" : "off")); | ||
3306 | hdw->cmd_buffer[0] = | ||
3307 | (onoff ? FX2CMD_ONAIR_DTV_STREAMING_ON : | ||
3308 | FX2CMD_ONAIR_DTV_STREAMING_OFF); | ||
3309 | status = pvr2_send_request(hdw, hdw->cmd_buffer, 1, NULL, 0); | ||
3310 | } while (0); LOCK_GIVE(hdw->ctl_lock); | ||
3311 | return status; | ||
3312 | } | 3351 | } |
3313 | 3352 | ||
3314 | 3353 | ||
@@ -3398,7 +3437,7 @@ static void pvr2_led_ctrl(struct pvr2_hdw *hdw,int onoff) | |||
3398 | /* Stop / start video stream transport */ | 3437 | /* Stop / start video stream transport */ |
3399 | static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl) | 3438 | static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl) |
3400 | { | 3439 | { |
3401 | int status,cc; | 3440 | int cc; |
3402 | if ((hdw->pathway_state == PVR2_PATHWAY_DIGITAL) && | 3441 | if ((hdw->pathway_state == PVR2_PATHWAY_DIGITAL) && |
3403 | (hdw->hdw_desc->digital_control_scheme == | 3442 | (hdw->hdw_desc->digital_control_scheme == |
3404 | PVR2_DIGITAL_SCHEME_HAUPPAUGE)) { | 3443 | PVR2_DIGITAL_SCHEME_HAUPPAUGE)) { |
@@ -3410,12 +3449,7 @@ static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl) | |||
3410 | FX2CMD_STREAMING_ON : | 3449 | FX2CMD_STREAMING_ON : |
3411 | FX2CMD_STREAMING_OFF); | 3450 | FX2CMD_STREAMING_OFF); |
3412 | } | 3451 | } |
3413 | 3452 | return pvr2_issue_simple_cmd(hdw,cc); | |
3414 | LOCK_TAKE(hdw->ctl_lock); do { | ||
3415 | hdw->cmd_buffer[0] = cc; | ||
3416 | status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0); | ||
3417 | } while (0); LOCK_GIVE(hdw->ctl_lock); | ||
3418 | return status; | ||
3419 | } | 3453 | } |
3420 | 3454 | ||
3421 | 3455 | ||