int cx25840_loadfw(struct i2c_client *client) { struct cx25840_state *state = to_state(i2c_get_clientdata(client)); const struct firmware *fw = NULL; u8 buffer[FWSEND]; const u8 *ptr; const char *fwname = get_fw_name(client); int size, retval; int max_buf_size = FWSEND; u32 gpio_oe = 0, gpio_da = 0; if (is_cx2388x(state)) { /* Preserve the GPIO OE and output bits */ gpio_oe = cx25840_read(client, 0x160); gpio_da = cx25840_read(client, 0x164); } /* cx231xx cannot accept more than 16 bytes at a time */ if (is_cx231xx(state) && max_buf_size > 16) max_buf_size = 16; if (request_firmware(&fw, fwname, FWDEV(client)) != 0) return -EINVAL; start_fw_load(client); buffer[0] = 0x08; buffer[1] = 0x02; size = fw->size; ptr = fw->data; while (size > 0) { int len = min(max_buf_size - 2, size); memcpy(buffer + 2, ptr, len); retval = fw_write(client, buffer, len + 2); if (retval < 0) { release_firmware(fw); return retval; } size -= len; ptr += len; } end_fw_load(client); size = fw->size; release_firmware(fw); if (is_cx2388x(state)) { /* Restore GPIO configuration after f/w load */ cx25840_write(client, 0x160, gpio_oe); cx25840_write(client, 0x164, gpio_da); } return check_fw_load(client, size); }
static int get_balance(struct i2c_client *client) { /* balance is 7 bit, 0 to -96dB */ /* check PATH1_BAL_LEVEL */ int balance = cx25840_read(client, 0x8d5) & 0x7f; /* check PATH1_BAL_LEFT */ if ((cx25840_read(client, 0x8d5) & 0x80) == 0) balance = 0x80 - balance; else balance = 0x80 + balance; return balance << 8; }
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) { v4l_err(client, "firmware %s load failed\n", firmware); return -EINVAL; } v4l_info(client, "loaded %s firmware (%d bytes)\n", firmware, size); return 0; }
static int get_treble(struct i2c_client *client) { /* treble is 49 steps +12dB to -12dB */ /* check PATH1_EQ_TREBLE_VOL */ int treble = cx25840_read(client, 0x8db) & 0x3f; treble = (((48 - treble) * 0xffff) + 47) / 48; return treble; }
static int get_bass(struct i2c_client *client) { /* bass is 49 steps +12dB to -12dB */ /* check PATH1_EQ_BASS_VOL */ int bass = cx25840_read(client, 0x8d9) & 0x3f; bass = (((48 - bass) * 0xffff) + 47) / 48; return bass; }
static int get_volume(struct i2c_client *client) { /* Volume runs +18dB to -96dB in 1/2dB steps * change to fit the msp3400 -114dB to +12dB range */ /* check PATH1_VOLUME */ int vol = 228 - cx25840_read(client, 0x8d4); vol = (vol / 2) + 23; return vol << 9; }
static int get_volume(struct i2c_client *client) { struct cx25840_state *state = i2c_get_clientdata(client); int vol; if (state->unmute_volume >= 0) return state->unmute_volume; /* Volume runs +18dB to -96dB in 1/2dB steps * change to fit the msp3400 -114dB to +12dB range */ /* check PATH1_VOLUME */ vol = 228 - cx25840_read(client, 0x8d4); vol = (vol / 2) + 23; return vol << 9; }
static int get_mute(struct i2c_client *client) { /* check SRC1_MUTE_EN */ return cx25840_read(client, 0x8d3) & 0x2 ? 1 : 0; }