Pull asus into release branch
[pandora-kernel.git] / drivers / media / video / pvrusb2 / pvrusb2-hdw.c
index 5e166ed..9916cf3 100644 (file)
@@ -36,6 +36,7 @@
 #include "pvrusb2-hdw-internal.h"
 #include "pvrusb2-encoder.h"
 #include "pvrusb2-debug.h"
+#include "pvrusb2-fx2-cmd.h"
 
 #define TV_MIN_FREQ     55250000L
 #define TV_MAX_FREQ    850000000L
@@ -270,8 +271,6 @@ static int pvr2_send_request_ex(struct pvr2_hdw *hdw,
                                unsigned int timeout,int probe_fl,
                                void *write_data,unsigned int write_len,
                                void *read_data,unsigned int read_len);
-static int pvr2_write_u16(struct pvr2_hdw *hdw, u16 data, int res);
-static int pvr2_write_u8(struct pvr2_hdw *hdw, u8 data, int res);
 
 static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp)
 {
@@ -1210,7 +1209,7 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
 {
        const struct firmware *fw_entry = NULL;
        void  *fw_ptr;
-       unsigned int pipe, fw_len, fw_done;
+       unsigned int pipe, fw_len, fw_done, bcnt, icnt;
        int actual_length;
        int ret = 0;
        int fwidx;
@@ -1247,8 +1246,13 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
        ret |= pvr2_write_register(hdw, 0xaa04, 0x00057810); /*unknown*/
        ret |= pvr2_write_register(hdw, 0xaa10, 0x00148500); /*unknown*/
        ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/
-       ret |= pvr2_write_u8(hdw, 0x52, 0);
-       ret |= pvr2_write_u16(hdw, 0x0600, 0);
+       LOCK_TAKE(hdw->ctl_lock); do {
+               hdw->cmd_buffer[0] = FX2CMD_FWPOST1;
+               ret |= pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
+               hdw->cmd_buffer[0] = FX2CMD_MEMSEL;
+               hdw->cmd_buffer[1] = 0;
+               ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,NULL,0);
+       } while (0); LOCK_GIVE(hdw->ctl_lock);
 
        if (ret) {
                pvr2_trace(PVR2_TRACE_ERROR_LEGS,
@@ -1261,11 +1265,11 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
 
        fw_len = fw_entry->size;
 
-       if (fw_len % FIRMWARE_CHUNK_SIZE) {
+       if (fw_len % sizeof(u32)) {
                pvr2_trace(PVR2_TRACE_ERROR_LEGS,
                           "size of %s firmware"
-                          " must be a multiple of 8192B",
-                          fw_files[fwidx]);
+                          " must be a multiple of %zu bytes",
+                          fw_files[fwidx],sizeof(u32));
                release_firmware(fw_entry);
                return -1;
        }
@@ -1280,18 +1284,21 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
 
        pipe = usb_sndbulkpipe(hdw->usb_dev, PVR2_FIRMWARE_ENDPOINT);
 
-       for (fw_done = 0 ; (fw_done < fw_len) && !ret ;
-            fw_done += FIRMWARE_CHUNK_SIZE ) {
-               int i;
-               memcpy(fw_ptr, fw_entry->data + fw_done, FIRMWARE_CHUNK_SIZE);
-               /* Usbsnoop log  shows that we must swap bytes... */
-               for (i = 0; i < FIRMWARE_CHUNK_SIZE/4 ; i++)
-                       ((u32 *)fw_ptr)[i] = ___swab32(((u32 *)fw_ptr)[i]);
-
-               ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,
-                                   FIRMWARE_CHUNK_SIZE,
+       fw_done = 0;
+       for (fw_done = 0; fw_done < fw_len;) {
+               bcnt = fw_len - fw_done;
+               if (bcnt > FIRMWARE_CHUNK_SIZE) bcnt = FIRMWARE_CHUNK_SIZE;
+               memcpy(fw_ptr, fw_entry->data + fw_done, bcnt);
+               /* Usbsnoop log shows that we must swap bytes... */
+               for (icnt = 0; icnt < bcnt/4 ; icnt++)
+                       ((u32 *)fw_ptr)[icnt] =
+                               ___swab32(((u32 *)fw_ptr)[icnt]);
+
+               ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,bcnt,
                                    &actual_length, HZ);
-               ret |= (actual_length != FIRMWARE_CHUNK_SIZE);
+               ret |= (actual_length != bcnt);
+               if (ret) break;
+               fw_done += bcnt;
        }
 
        trace_firmware("upload of %s : %i / %i ",
@@ -1310,7 +1317,11 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
 
        ret |= pvr2_write_register(hdw, 0x9054, 0xffffffff); /*reset hw blocks*/
        ret |= pvr2_write_register(hdw, 0x9058, 0xffffffe8); /*VPU ctrl*/
-       ret |= pvr2_write_u16(hdw, 0x0600, 0);
+       LOCK_TAKE(hdw->ctl_lock); do {
+               hdw->cmd_buffer[0] = FX2CMD_MEMSEL;
+               hdw->cmd_buffer[1] = 0;
+               ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,NULL,0);
+       } while (0); LOCK_GIVE(hdw->ctl_lock);
 
        if (ret) {
                pvr2_trace(PVR2_TRACE_ERROR_LEGS,
@@ -1647,7 +1658,7 @@ static int pvr2_hdw_check_firmware(struct pvr2_hdw *hdw)
           firmware needs be loaded. */
        int result;
        LOCK_TAKE(hdw->ctl_lock); do {
-               hdw->cmd_buffer[0] = 0xeb;
+               hdw->cmd_buffer[0] = FX2CMD_GET_EEPROM_ADDR;
                result = pvr2_send_request_ex(hdw,HZ*1,!0,
                                           hdw->cmd_buffer,1,
                                           hdw->cmd_buffer,1);
@@ -2526,7 +2537,7 @@ int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw)
 {
        int result;
        LOCK_TAKE(hdw->ctl_lock); do {
-               hdw->cmd_buffer[0] = 0x0b;
+               hdw->cmd_buffer[0] = FX2CMD_GET_USB_SPEED;
                result = pvr2_send_request(hdw,
                                           hdw->cmd_buffer,1,
                                           hdw->cmd_buffer,1);
@@ -2976,7 +2987,7 @@ int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data)
 
        LOCK_TAKE(hdw->ctl_lock);
 
-       hdw->cmd_buffer[0] = 0x04;  /* write register prefix */
+       hdw->cmd_buffer[0] = FX2CMD_REG_WRITE;  /* write register prefix */
        PVR2_DECOMPOSE_LE(hdw->cmd_buffer,1,data);
        hdw->cmd_buffer[5] = 0;
        hdw->cmd_buffer[6] = (reg >> 8) & 0xff;
@@ -2997,7 +3008,7 @@ static int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data)
 
        LOCK_TAKE(hdw->ctl_lock);
 
-       hdw->cmd_buffer[0] = 0x05;  /* read register prefix */
+       hdw->cmd_buffer[0] = FX2CMD_REG_READ;  /* read register prefix */
        hdw->cmd_buffer[1] = 0;
        hdw->cmd_buffer[2] = 0;
        hdw->cmd_buffer[3] = 0;
@@ -3015,39 +3026,6 @@ static int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data)
 }
 
 
-static int pvr2_write_u16(struct pvr2_hdw *hdw, u16 data, int res)
-{
-       int ret;
-
-       LOCK_TAKE(hdw->ctl_lock);
-
-       hdw->cmd_buffer[0] = (data >> 8) & 0xff;
-       hdw->cmd_buffer[1] = data & 0xff;
-
-       ret = pvr2_send_request(hdw, hdw->cmd_buffer, 2, hdw->cmd_buffer, res);
-
-       LOCK_GIVE(hdw->ctl_lock);
-
-       return ret;
-}
-
-
-static int pvr2_write_u8(struct pvr2_hdw *hdw, u8 data, int res)
-{
-       int ret;
-
-       LOCK_TAKE(hdw->ctl_lock);
-
-       hdw->cmd_buffer[0] = data;
-
-       ret = pvr2_send_request(hdw, hdw->cmd_buffer, 1, hdw->cmd_buffer, res);
-
-       LOCK_GIVE(hdw->ctl_lock);
-
-       return ret;
-}
-
-
 static void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw)
 {
        if (!hdw->flag_ok) return;
@@ -3121,7 +3099,7 @@ int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw)
        LOCK_TAKE(hdw->ctl_lock); do {
                pvr2_trace(PVR2_TRACE_INIT,"Requesting uproc hard reset");
                hdw->flag_ok = !0;
-               hdw->cmd_buffer[0] = 0xdd;
+               hdw->cmd_buffer[0] = FX2CMD_DEEP_RESET;
                status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
        } while (0); LOCK_GIVE(hdw->ctl_lock);
        return status;
@@ -3133,7 +3111,7 @@ int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw)
        int status;
        LOCK_TAKE(hdw->ctl_lock); do {
                pvr2_trace(PVR2_TRACE_INIT,"Requesting powerup");
-               hdw->cmd_buffer[0] = 0xde;
+               hdw->cmd_buffer[0] = FX2CMD_POWER_ON;
                status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
        } while (0); LOCK_GIVE(hdw->ctl_lock);
        return status;
@@ -3166,7 +3144,8 @@ static int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl)
 {
        int status;
        LOCK_TAKE(hdw->ctl_lock); do {
-               hdw->cmd_buffer[0] = (runFl ? 0x36 : 0x37);
+               hdw->cmd_buffer[0] =
+                       (runFl ? FX2CMD_STREAMING_ON : FX2CMD_STREAMING_OFF);
                status = pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0);
        } while (0); LOCK_GIVE(hdw->ctl_lock);
        if (!status) {
@@ -3265,7 +3244,7 @@ static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw)
 {
        int result;
        LOCK_TAKE(hdw->ctl_lock); do {
-               hdw->cmd_buffer[0] = 0xeb;
+               hdw->cmd_buffer[0] = FX2CMD_GET_EEPROM_ADDR;
                result = pvr2_send_request(hdw,
                                           hdw->cmd_buffer,1,
                                           hdw->cmd_buffer,1);
@@ -3277,8 +3256,8 @@ static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw)
 
 
 int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
-                            u32 chip_id,unsigned long reg_id,
-                            int setFl,u32 *val_ptr)
+                            u32 match_type, u32 match_chip, u64 reg_id,
+                            int setFl,u64 *val_ptr)
 {
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        struct list_head *item;
@@ -3287,16 +3266,21 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
        int stat = 0;
        int okFl = 0;
 
-       req.i2c_id = chip_id;
+       if (!capable(CAP_SYS_ADMIN)) return -EPERM;
+
+       req.match_type = match_type;
+       req.match_chip = match_chip;
        req.reg = reg_id;
        if (setFl) req.val = *val_ptr;
        mutex_lock(&hdw->i2c_list_lock); do {
                list_for_each(item,&hdw->i2c_clients) {
                        cp = list_entry(item,struct pvr2_i2c_client,list);
-                       if (cp->client->driver->id != chip_id) continue;
+                       if (!v4l2_chip_match_i2c_client(cp->client, req.match_type, req.match_chip)) {
+                               continue;
+                       }
                        stat = pvr2_i2c_client_cmd(
-                               cp,(setFl ? VIDIOC_INT_S_REGISTER :
-                                   VIDIOC_INT_G_REGISTER),&req);
+                               cp,(setFl ? VIDIOC_DBG_S_REGISTER :
+                                   VIDIOC_DBG_G_REGISTER),&req);
                        if (!setFl) *val_ptr = req.val;
                        okFl = !0;
                        break;