Pull acpica into release branch
[pandora-kernel.git] / drivers / media / video / cx25840 / cx25840-firmware.c
index df9d50a..1958d40 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-
 #include <linux/module.h>
 #include <linux/i2c.h>
 #include <linux/i2c-algo-bit.h>
 #include <linux/firmware.h>
 #include <media/v4l2-common.h>
+#include <media/cx25840.h>
 
-#include "cx25840.h"
+#include "cx25840-core.h"
 
 #define FWFILE "v4l-cx25840.fw"
-#define FWSEND 1024
+
+/*
+ * Mike Isely <isely@pobox.com> - The FWSEND parameter controls the
+ * size of the firmware chunks sent down the I2C bus to the chip.
+ * Previously this had been set to 1024 but unfortunately some I2C
+ * implementations can't transfer data in such big gulps.
+ * Specifically, the pvrusb2 driver has a hard limit of around 60
+ * bytes, due to the encapsulation there of I2C traffic into USB
+ * messages.  So we have to significantly reduce this parameter.
+ */
+#define FWSEND 48
 
 #define FWDEV(x) &((x)->adapter->dev)
 
-static int fastfw = 1;
 static char *firmware = FWFILE;
 
-module_param(fastfw, bool, 0444);
 module_param(firmware, charp, 0444);
 
-MODULE_PARM_DESC(fastfw, "Load firmware fast [0=100MHz 1=333MHz (default)]");
 MODULE_PARM_DESC(firmware, "Firmware image [default: " FWFILE "]");
 
-static inline void set_i2c_delay(struct i2c_client *client, int delay)
-{
-       struct i2c_algo_bit_data *algod = client->adapter->algo_data;
-
-       /* We aren't guaranteed to be using algo_bit,
-        * so avoid the null pointer dereference
-        * and disable the 'fast firmware load' */
-       if (algod) {
-               algod->udelay = delay;
-       } else {
-               fastfw = 0;
-       }
-}
-
-static inline void start_fw_load(struct i2c_client *client)
+static void start_fw_load(struct i2c_client *client)
 {
        /* DL_ADDR_LB=0 DL_ADDR_HB=0 */
        cx25840_write(client, 0x800, 0x00);
@@ -61,57 +54,38 @@ static inline void start_fw_load(struct i2c_client *client)
        cx25840_write(client, 0x803, 0x0b);
        /* AUTO_INC_DIS=1 */
        cx25840_write(client, 0x000, 0x20);
-
-       if (fastfw)
-               set_i2c_delay(client, 3);
 }
 
-static inline void end_fw_load(struct i2c_client *client)
+static void end_fw_load(struct i2c_client *client)
 {
-       if (fastfw)
-               set_i2c_delay(client, 10);
-
        /* AUTO_INC_DIS=0 */
        cx25840_write(client, 0x000, 0x00);
        /* DL_ENABLE=0 */
        cx25840_write(client, 0x803, 0x03);
 }
 
-static inline int check_fw_load(struct i2c_client *client, int size)
+static int check_fw_load(struct i2c_client *client, int size)
 {
        /* DL_ADDR_HB DL_ADDR_LB */
        int s = cx25840_read(client, 0x801) << 8;
        s |= cx25840_read(client, 0x800);
 
        if (size != s) {
-               cx25840_err("firmware %s load failed\n", firmware);
+               v4l_err(client, "firmware %s load failed\n", firmware);
                return -EINVAL;
        }
 
-       cx25840_info("loaded %s firmware (%d bytes)\n", firmware, size);
+       v4l_info(client, "loaded %s firmware (%d bytes)\n", firmware, size);
        return 0;
 }
 
-static inline int fw_write(struct i2c_client *client, u8 * data, int size)
+static int fw_write(struct i2c_client *client, u8 * data, int size)
 {
-       if (i2c_master_send(client, data, size) < size) {
-
-               if (fastfw) {
-                       cx25840_err("333MHz i2c firmware load failed\n");
-                       fastfw = 0;
-                       set_i2c_delay(client, 10);
-
-                       if (i2c_master_send(client, data, size) < size) {
-                               cx25840_err
-                                   ("100MHz i2c firmware load failed\n");
-                               return -ENOSYS;
-                       }
-
-               } else {
-                       cx25840_err("firmware load i2c failure\n");
-                       return -ENOSYS;
-               }
+       int sent;
 
+       if ((sent = i2c_master_send(client, data, size)) < size) {
+               v4l_err(client, "firmware load i2c failure\n");
+               return -ENOSYS;
        }
 
        return 0;
@@ -124,7 +98,7 @@ int cx25840_loadfw(struct i2c_client *client)
        int size, send, retval;
 
        if (request_firmware(&fw, firmware, FWDEV(client)) != 0) {
-               cx25840_err("unable to open firmware %s\n", firmware);
+               v4l_err(client, "unable to open firmware %s\n", firmware);
                return -EINVAL;
        }