^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * mxl111sf-phy.c - driver for the MaxLinear MXL111SF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "mxl111sf-phy.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "mxl111sf-reg.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) int mxl111sf_init_tuner_demod(struct mxl111sf_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) struct mxl111sf_reg_ctrl_info mxl_111_overwrite_default[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) {0x07, 0xff, 0x0c},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) {0x58, 0xff, 0x9d},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) {0x09, 0xff, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) {0x06, 0xff, 0x06},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) {0xc8, 0xff, 0x40}, /* ED_LE_WIN_OLD = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) {0x8d, 0x01, 0x01}, /* NEGATE_Q */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) {0x32, 0xff, 0xac}, /* DIG_RFREFSELECT = 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) {0x42, 0xff, 0x43}, /* DIG_REG_AMP = 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) {0x74, 0xff, 0xc4}, /* SSPUR_FS_PRIO = 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) {0x71, 0xff, 0xe6}, /* SPUR_ROT_PRIO_VAL = 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) {0x83, 0xff, 0x64}, /* INF_FILT1_THD_SC = 100 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) {0x85, 0xff, 0x64}, /* INF_FILT2_THD_SC = 100 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) {0x88, 0xff, 0xf0}, /* INF_THD = 240 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) {0x6f, 0xf0, 0xb0}, /* DFE_DLY = 11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) {0x00, 0xff, 0x01}, /* Change to page 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) {0x81, 0xff, 0x11}, /* DSM_FERR_BYPASS = 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {0xf4, 0xff, 0x07}, /* DIG_FREQ_CORR = 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) {0xd4, 0x1f, 0x0f}, /* SPUR_TEST_NOISE_TH = 15 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) {0xd6, 0xff, 0x0c}, /* SPUR_TEST_NOISE_PAPR = 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {0x00, 0xff, 0x00}, /* Change to page 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {0, 0, 0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) mxl_debug("()");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return mxl111sf_ctrl_program_regs(state, mxl_111_overwrite_default);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) int mxl1x1sf_soft_reset(struct mxl111sf_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) mxl_debug("()");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) ret = mxl111sf_write_reg(state, 0xff, 0x00); /* AIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (mxl_fail(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) ret = mxl111sf_write_reg(state, 0x02, 0x01); /* get out of reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) mxl_fail(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) int mxl1x1sf_set_device_mode(struct mxl111sf_state *state, int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) mxl_debug("(%s)", MXL_SOC_MODE == mode ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) "MXL_SOC_MODE" : "MXL_TUNER_MODE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* set device mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) ret = mxl111sf_write_reg(state, 0x03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) MXL_SOC_MODE == mode ? 0x01 : 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (mxl_fail(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) ret = mxl111sf_write_reg_mask(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) 0x7d, 0x40, MXL_SOC_MODE == mode ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) 0x00 : /* enable impulse noise filter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) INF_BYP = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) 0x40); /* disable impulse noise filter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) INF_BYP = 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (mxl_fail(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) state->device_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* power up tuner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) int mxl1x1sf_top_master_ctrl(struct mxl111sf_state *state, int onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) mxl_debug("(%d)", onoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return mxl111sf_write_reg(state, 0x01, onoff ? 0x01 : 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) int mxl111sf_disable_656_port(struct mxl111sf_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) mxl_debug("()");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return mxl111sf_write_reg_mask(state, 0x12, 0x04, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) int mxl111sf_enable_usb_output(struct mxl111sf_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) mxl_debug("()");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return mxl111sf_write_reg_mask(state, 0x17, 0x40, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* initialize TSIF as input port of MxL1X1SF for MPEG2 data transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) int mxl111sf_config_mpeg_in(struct mxl111sf_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) unsigned int parallel_serial,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) unsigned int msb_lsb_1st,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) unsigned int clock_phase,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) unsigned int mpeg_valid_pol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) unsigned int mpeg_sync_pol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) u8 mode, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) mxl_debug("(%u,%u,%u,%u,%u)", parallel_serial, msb_lsb_1st,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) clock_phase, mpeg_valid_pol, mpeg_sync_pol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /* Enable PIN MUX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) ret = mxl111sf_write_reg(state, V6_PIN_MUX_MODE_REG, V6_ENABLE_PIN_MUX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) mxl_fail(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /* Configure MPEG Clock phase */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) mxl111sf_read_reg(state, V6_MPEG_IN_CLK_INV_REG, &mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (clock_phase == TSIF_NORMAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) mode &= ~V6_INVERTED_CLK_PHASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) mode |= V6_INVERTED_CLK_PHASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) ret = mxl111sf_write_reg(state, V6_MPEG_IN_CLK_INV_REG, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) mxl_fail(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /* Configure data input mode, MPEG Valid polarity, MPEG Sync polarity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * Get current configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) ret = mxl111sf_read_reg(state, V6_MPEG_IN_CTRL_REG, &mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) mxl_fail(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /* Data Input mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (parallel_serial == TSIF_INPUT_PARALLEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /* Disable serial mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) mode &= ~V6_MPEG_IN_DATA_SERIAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* Enable Parallel mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) mode |= V6_MPEG_IN_DATA_PARALLEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /* Disable Parallel mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) mode &= ~V6_MPEG_IN_DATA_PARALLEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /* Enable Serial Mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) mode |= V6_MPEG_IN_DATA_SERIAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* If serial interface is chosen, configure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) MSB or LSB order in transmission */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ret = mxl111sf_read_reg(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) V6_MPEG_INOUT_BIT_ORDER_CTRL_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) mxl_fail(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (msb_lsb_1st == MPEG_SER_MSB_FIRST_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) tmp |= V6_MPEG_SER_MSB_FIRST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) tmp &= ~V6_MPEG_SER_MSB_FIRST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) ret = mxl111sf_write_reg(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) V6_MPEG_INOUT_BIT_ORDER_CTRL_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) mxl_fail(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /* MPEG Sync polarity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (mpeg_sync_pol == TSIF_NORMAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) mode &= ~V6_INVERTED_MPEG_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) mode |= V6_INVERTED_MPEG_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) /* MPEG Valid polarity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (mpeg_valid_pol == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) mode &= ~V6_INVERTED_MPEG_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) mode |= V6_INVERTED_MPEG_VALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) ret = mxl111sf_write_reg(state, V6_MPEG_IN_CTRL_REG, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) mxl_fail(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) int mxl111sf_init_i2s_port(struct mxl111sf_state *state, u8 sample_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static struct mxl111sf_reg_ctrl_info init_i2s[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {0x1b, 0xff, 0x1e}, /* pin mux mode, Choose 656/I2S input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {0x15, 0x60, 0x60}, /* Enable I2S */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {0x17, 0xe0, 0x20}, /* Input, MPEG MODE USB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) Inverted 656 Clock, I2S_SOFT_RESET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 0 : Normal operation, 1 : Reset State */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {0x12, 0x01, 0x00}, /* AUDIO_IRQ_CLR (Overflow Indicator) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {0x00, 0xff, 0x02}, /* Change to Control Page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {0x26, 0x0d, 0x0d}, /* I2S_MODE & BT656_SRC_SEL for FPGA only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {0x00, 0xff, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {0, 0, 0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) mxl_debug("(0x%02x)", sample_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) ret = mxl111sf_ctrl_program_regs(state, init_i2s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (mxl_fail(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) ret = mxl111sf_write_reg(state, V6_I2S_NUM_SAMPLES_REG, sample_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) mxl_fail(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) int mxl111sf_disable_i2s_port(struct mxl111sf_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static struct mxl111sf_reg_ctrl_info disable_i2s[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) {0x15, 0x40, 0x00},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {0, 0, 0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) mxl_debug("()");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return mxl111sf_ctrl_program_regs(state, disable_i2s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) int mxl111sf_config_i2s(struct mxl111sf_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) u8 msb_start_pos, u8 data_width)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) u8 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) mxl_debug("(0x%02x, 0x%02x)", msb_start_pos, data_width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) ret = mxl111sf_read_reg(state, V6_I2S_STREAM_START_BIT_REG, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (mxl_fail(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) tmp &= 0xe0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) tmp |= msb_start_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) ret = mxl111sf_write_reg(state, V6_I2S_STREAM_START_BIT_REG, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (mxl_fail(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) ret = mxl111sf_read_reg(state, V6_I2S_STREAM_END_BIT_REG, &tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (mxl_fail(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) tmp &= 0xe0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) tmp |= data_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) ret = mxl111sf_write_reg(state, V6_I2S_STREAM_END_BIT_REG, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) mxl_fail(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) int mxl111sf_config_spi(struct mxl111sf_state *state, int onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) mxl_debug("(%d)", onoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) ret = mxl111sf_write_reg(state, 0x00, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (mxl_fail(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) ret = mxl111sf_read_reg(state, V8_SPI_MODE_REG, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (mxl_fail(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) val |= 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) val &= ~0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) ret = mxl111sf_write_reg(state, V8_SPI_MODE_REG, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (mxl_fail(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) ret = mxl111sf_write_reg(state, 0x00, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) mxl_fail(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) int mxl111sf_idac_config(struct mxl111sf_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) u8 control_mode, u8 current_setting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) u8 current_value, u8 hysteresis_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) /* current value will be set for both automatic & manual IDAC control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) val = current_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (control_mode == IDAC_MANUAL_CONTROL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /* enable manual control of IDAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) val |= IDAC_MANUAL_CONTROL_BIT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (current_setting == IDAC_CURRENT_SINKING_ENABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) /* enable current sinking in manual mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) val |= IDAC_CURRENT_SINKING_BIT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /* disable current sinking in manual mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) val &= ~IDAC_CURRENT_SINKING_BIT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /* disable manual control of IDAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) val &= ~IDAC_MANUAL_CONTROL_BIT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /* set hysteresis value reg: 0x0B<5:0> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) ret = mxl111sf_write_reg(state, V6_IDAC_HYSTERESIS_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) (hysteresis_value & 0x3F));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) mxl_fail(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) ret = mxl111sf_write_reg(state, V6_IDAC_SETTINGS_REG, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) mxl_fail(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }