aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMike Isely <isely@pobox.com>2008-03-28 04:38:54 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-04-24 13:09:47 -0400
commit1c9d10d4d2e791a9eacd9f919dec78c5bc6737e8 (patch)
treea63ebc17d527109d3ab65cecd04bc03166a4245b /drivers
parent448cb48e6e2fcd3a948cc549c5c6ab7f84440a54 (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')
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c198
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 a26b5251ec1..063aed0067c 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
219struct pvr2_fx2cmd_desc {
220 unsigned char id;
221 unsigned char *desc;
222};
223
224static 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
219static void pvr2_hdw_state_sched(struct pvr2_hdw *); 252static void pvr2_hdw_state_sched(struct pvr2_hdw *);
220static int pvr2_hdw_state_eval(struct pvr2_hdw *); 253static int pvr2_hdw_state_eval(struct pvr2_hdw *);
221static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *,unsigned long); 254static 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);
231static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw); 264static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw);
232static void pvr2_hdw_quiescent_timeout(unsigned long); 265static void pvr2_hdw_quiescent_timeout(unsigned long);
233static void pvr2_hdw_encoder_wait_timeout(unsigned long); 266static void pvr2_hdw_encoder_wait_timeout(unsigned long);
267static int pvr2_issue_simple_cmd(struct pvr2_hdw *,u32);
234static int pvr2_send_request_ex(struct pvr2_hdw *hdw, 268static 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
3122static 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
3096int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data) 3182int 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
3201int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw) 3287int 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
3213static 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
3229int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw) 3293int 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
3234int pvr2_hdw_cmd_powerdown(struct pvr2_hdw *hdw) 3299int 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
3261static int pvr2_hdw_cmd_hcw_demod_reset(struct pvr2_hdw *hdw, int onoff) 3326static 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
3279static int pvr2_hdw_cmd_onair_fe_power_ctrl(struct pvr2_hdw *hdw, int onoff) 3336static 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
3298static int pvr2_hdw_cmd_onair_digital_path_ctrl(struct pvr2_hdw *hdw, 3345static 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 */
3399static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl) 3438static 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