^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * drivers/mfd/si476x-cmd.c -- Subroutines implementing command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * protocol of si476x series of chips
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2012 Innovative Converged Devices(ICD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2013 Andrey Smirnov
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/videodev2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/mfd/si476x-core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define msb(x) ((u8)((u16) x >> 8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define lsb(x) ((u8)((u16) x & 0x00FF))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define CMD_POWER_UP 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define CMD_POWER_UP_A10_NRESP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define CMD_POWER_UP_A10_NARGS 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define CMD_POWER_UP_A20_NRESP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define CMD_POWER_UP_A20_NARGS 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define POWER_UP_DELAY_MS 110
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define CMD_POWER_DOWN 0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define CMD_POWER_DOWN_A10_NRESP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define CMD_POWER_DOWN_A20_NRESP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define CMD_POWER_DOWN_A20_NARGS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define CMD_FUNC_INFO 0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define CMD_FUNC_INFO_NRESP 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define CMD_SET_PROPERTY 0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define CMD_SET_PROPERTY_NARGS 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define CMD_SET_PROPERTY_NRESP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define CMD_GET_PROPERTY 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define CMD_GET_PROPERTY_NARGS 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define CMD_GET_PROPERTY_NRESP 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define CMD_AGC_STATUS 0x17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define CMD_AGC_STATUS_NRESP_A10 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define CMD_AGC_STATUS_NRESP_A20 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define PIN_CFG_BYTE(x) (0x7F & (x))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define CMD_DIG_AUDIO_PIN_CFG 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define CMD_DIG_AUDIO_PIN_CFG_NARGS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define CMD_DIG_AUDIO_PIN_CFG_NRESP 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define CMD_ZIF_PIN_CFG 0x19
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define CMD_ZIF_PIN_CFG_NARGS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define CMD_ZIF_PIN_CFG_NRESP 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define CMD_IC_LINK_GPO_CTL_PIN_CFG 0x1A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define CMD_IC_LINK_GPO_CTL_PIN_CFG_NARGS 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define CMD_IC_LINK_GPO_CTL_PIN_CFG_NRESP 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define CMD_ANA_AUDIO_PIN_CFG 0x1B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define CMD_ANA_AUDIO_PIN_CFG_NARGS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define CMD_ANA_AUDIO_PIN_CFG_NRESP 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define CMD_INTB_PIN_CFG 0x1C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define CMD_INTB_PIN_CFG_NARGS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define CMD_INTB_PIN_CFG_A10_NRESP 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define CMD_INTB_PIN_CFG_A20_NRESP 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define CMD_FM_TUNE_FREQ 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define CMD_FM_TUNE_FREQ_A10_NARGS 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define CMD_FM_TUNE_FREQ_A20_NARGS 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define CMD_FM_TUNE_FREQ_NRESP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define CMD_FM_RSQ_STATUS 0x32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define CMD_FM_RSQ_STATUS_A10_NARGS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define CMD_FM_RSQ_STATUS_A10_NRESP 17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define CMD_FM_RSQ_STATUS_A30_NARGS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define CMD_FM_RSQ_STATUS_A30_NRESP 23
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define CMD_FM_SEEK_START 0x31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define CMD_FM_SEEK_START_NARGS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define CMD_FM_SEEK_START_NRESP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define CMD_FM_RDS_STATUS 0x36
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define CMD_FM_RDS_STATUS_NARGS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define CMD_FM_RDS_STATUS_NRESP 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define CMD_FM_RDS_BLOCKCOUNT 0x37
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define CMD_FM_RDS_BLOCKCOUNT_NARGS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define CMD_FM_RDS_BLOCKCOUNT_NRESP 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define CMD_FM_PHASE_DIVERSITY 0x38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define CMD_FM_PHASE_DIVERSITY_NARGS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define CMD_FM_PHASE_DIVERSITY_NRESP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define CMD_FM_PHASE_DIV_STATUS 0x39
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define CMD_FM_PHASE_DIV_STATUS_NRESP 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define CMD_AM_TUNE_FREQ 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define CMD_AM_TUNE_FREQ_NARGS 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define CMD_AM_TUNE_FREQ_NRESP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define CMD_AM_RSQ_STATUS 0x42
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define CMD_AM_RSQ_STATUS_NARGS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define CMD_AM_RSQ_STATUS_NRESP 13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define CMD_AM_SEEK_START 0x41
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define CMD_AM_SEEK_START_NARGS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define CMD_AM_SEEK_START_NRESP 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define CMD_AM_ACF_STATUS 0x45
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define CMD_AM_ACF_STATUS_NRESP 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define CMD_AM_ACF_STATUS_NARGS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define CMD_FM_ACF_STATUS 0x35
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define CMD_FM_ACF_STATUS_NRESP 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define CMD_FM_ACF_STATUS_NARGS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define CMD_MAX_ARGS_COUNT (10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) enum si476x_acf_status_report_bits {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) SI476X_ACF_BLEND_INT = (1 << 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) SI476X_ACF_HIBLEND_INT = (1 << 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) SI476X_ACF_HICUT_INT = (1 << 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) SI476X_ACF_CHBW_INT = (1 << 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) SI476X_ACF_SOFTMUTE_INT = (1 << 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) SI476X_ACF_SMUTE = (1 << 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) SI476X_ACF_SMATTN = 0x1f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) SI476X_ACF_PILOT = (1 << 7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) SI476X_ACF_STBLEND = ~SI476X_ACF_PILOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) enum si476x_agc_status_report_bits {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) SI476X_AGC_MXHI = (1 << 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) SI476X_AGC_MXLO = (1 << 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) SI476X_AGC_LNAHI = (1 << 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) SI476X_AGC_LNALO = (1 << 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) enum si476x_errors {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) SI476X_ERR_BAD_COMMAND = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) SI476X_ERR_BAD_ARG1 = 0x11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) SI476X_ERR_BAD_ARG2 = 0x12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) SI476X_ERR_BAD_ARG3 = 0x13,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) SI476X_ERR_BAD_ARG4 = 0x14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) SI476X_ERR_BUSY = 0x18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) SI476X_ERR_BAD_INTERNAL_MEMORY = 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) SI476X_ERR_BAD_PATCH = 0x30,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) SI476X_ERR_BAD_BOOT_MODE = 0x31,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) SI476X_ERR_BAD_PROPERTY = 0x40,
^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) static int si476x_core_parse_and_nag_about_error(struct si476x_core *core)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) char *cause;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) u8 buffer[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (core->revision != SI476X_REVISION_A10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) err = si476x_core_i2c_xfer(core, SI476X_I2C_RECV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) buffer, sizeof(buffer));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (err == sizeof(buffer)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) switch (buffer[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) case SI476X_ERR_BAD_COMMAND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) cause = "Bad command";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) case SI476X_ERR_BAD_ARG1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) cause = "Bad argument #1";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) case SI476X_ERR_BAD_ARG2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) cause = "Bad argument #2";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) case SI476X_ERR_BAD_ARG3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) cause = "Bad argument #3";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) case SI476X_ERR_BAD_ARG4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) cause = "Bad argument #4";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) case SI476X_ERR_BUSY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) cause = "Chip is busy";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) case SI476X_ERR_BAD_INTERNAL_MEMORY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) cause = "Bad internal memory";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) case SI476X_ERR_BAD_PATCH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) cause = "Bad patch";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) case SI476X_ERR_BAD_BOOT_MODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) cause = "Bad boot mode";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) case SI476X_ERR_BAD_PROPERTY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) cause = "Bad property";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) cause = "Unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) dev_err(&core->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) "[Chip error status]: %s\n", cause);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) dev_err(&core->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) "Failed to fetch error code\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) err = (err >= 0) ? -EIO : err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * si476x_core_send_command() - sends a command to si476x and waits its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * @core: si476x_device structure for the device we are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * communicating with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * @command: command id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * @args: command arguments we are sending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * @argn: actual size of @args
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * @resp: buffer to place the expected response from the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * @respn: actual size of @resp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * @usecs: amount of time to wait before reading the response (in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * usecs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * Function returns 0 on succsess and negative error code on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static int si476x_core_send_command(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) const u8 command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) const u8 args[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) const int argn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) u8 resp[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) const int respn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) const int usecs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct i2c_client *client = core->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) u8 data[CMD_MAX_ARGS_COUNT + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (argn > CMD_MAX_ARGS_COUNT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (!client->adapter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /* First send the command and its arguments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) data[0] = command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) memcpy(&data[1], args, argn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) dev_dbg(&client->dev, "Command:\n %*ph\n", argn + 1, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) err = si476x_core_i2c_xfer(core, SI476X_I2C_SEND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) (char *) data, argn + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (err != argn + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) dev_err(&core->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) "Error while sending command 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) err = (err >= 0) ? -EIO : err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) /* Set CTS to zero only after the command is send to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * possible racing conditions when working in polling mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) atomic_set(&core->cts, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) /* if (unlikely(command == CMD_POWER_DOWN) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (!wait_event_timeout(core->command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) atomic_read(&core->cts),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) usecs_to_jiffies(usecs) + 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) dev_warn(&core->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) "(%s) [CMD 0x%02x] Answer timeout.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) __func__, command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) When working in polling mode, for some reason the tuner will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) report CTS bit as being set in the first status byte read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) but all the consequtive ones will return zeros until the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) tuner is actually completed the POWER_UP command. To
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) workaround that we wait for second CTS to be reported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (unlikely(!core->client->irq && command == CMD_POWER_UP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (!wait_event_timeout(core->command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) atomic_read(&core->cts),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) usecs_to_jiffies(usecs) + 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) dev_warn(&core->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) "(%s) Power up took too much time.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /* Then get the response */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) err = si476x_core_i2c_xfer(core, SI476X_I2C_RECV, resp, respn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (err != respn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) dev_err(&core->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) "Error while reading response for command 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) err = (err >= 0) ? -EIO : err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) dev_dbg(&client->dev, "Response:\n %*ph\n", respn, resp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (resp[0] & SI476X_ERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) dev_err(&core->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) "[CMD 0x%02x] Chip set error flag\n", command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) err = si476x_core_parse_and_nag_about_error(core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (!(resp[0] & SI476X_CTS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) static int si476x_cmd_clear_stc(struct si476x_core *core)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) struct si476x_rsq_status_args args = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) .primary = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) .rsqack = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) .attune = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) .cancel = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) .stcack = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) switch (core->power_up_parameters.func) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) case SI476X_FUNC_FM_RECEIVER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) err = si476x_core_cmd_fm_rsq_status(core, &args, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) case SI476X_FUNC_AM_RECEIVER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) err = si476x_core_cmd_am_rsq_status(core, &args, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) static int si476x_cmd_tune_seek_freq(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) uint8_t cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) const uint8_t args[], size_t argn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) uint8_t *resp, size_t respn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) atomic_set(&core->stc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) err = si476x_core_send_command(core, cmd, args, argn, resp, respn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) SI476X_TIMEOUT_TUNE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) wait_event_killable(core->tuning,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) atomic_read(&core->stc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) si476x_cmd_clear_stc(core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * si476x_cmd_func_info() - send 'FUNC_INFO' command to the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * @core: device to send the command to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * @info: struct si476x_func_info to fill all the information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * returned by the command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * The command requests the firmware and patch version for currently
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * loaded firmware (dependent on the function of the device FM/AM/WB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * Function returns 0 on succsess and negative error code on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) int si476x_core_cmd_func_info(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct si476x_func_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) u8 resp[CMD_FUNC_INFO_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) err = si476x_core_send_command(core, CMD_FUNC_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) SI476X_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) info->firmware.major = resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) info->firmware.minor[0] = resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) info->firmware.minor[1] = resp[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) info->patch_id = ((u16) resp[4] << 8) | resp[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) info->func = resp[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) EXPORT_SYMBOL_GPL(si476x_core_cmd_func_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) * si476x_cmd_set_property() - send 'SET_PROPERTY' command to the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) * @core: device to send the command to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * @property: property address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) * @value: property value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) * Function returns 0 on succsess and negative error code on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) * failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) int si476x_core_cmd_set_property(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) u16 property, u16 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) u8 resp[CMD_SET_PROPERTY_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) const u8 args[CMD_SET_PROPERTY_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) msb(property),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) lsb(property),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) msb(value),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) lsb(value),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return si476x_core_send_command(core, CMD_SET_PROPERTY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) args, ARRAY_SIZE(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) SI476X_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) EXPORT_SYMBOL_GPL(si476x_core_cmd_set_property);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) * si476x_cmd_get_property() - send 'GET_PROPERTY' command to the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * @core: device to send the command to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * @property: property address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) * Function return the value of property as u16 on success or a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) * negative error on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) int si476x_core_cmd_get_property(struct si476x_core *core, u16 property)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) u8 resp[CMD_GET_PROPERTY_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) const u8 args[CMD_GET_PROPERTY_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) msb(property),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) lsb(property),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) err = si476x_core_send_command(core, CMD_GET_PROPERTY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) args, ARRAY_SIZE(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) SI476X_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return get_unaligned_be16(resp + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) EXPORT_SYMBOL_GPL(si476x_core_cmd_get_property);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * si476x_cmd_dig_audio_pin_cfg() - send 'DIG_AUDIO_PIN_CFG' command to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) * @core: device to send the command to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * @dclk: DCLK pin function configuration:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) * #SI476X_DCLK_NOOP - do not modify the behaviour
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) * #SI476X_DCLK_TRISTATE - put the pin in tristate condition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) * enable 1MOhm pulldown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) * #SI476X_DCLK_DAUDIO - set the pin to be a part of digital
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) * audio interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) * @dfs: DFS pin function configuration:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) * #SI476X_DFS_NOOP - do not modify the behaviour
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) * #SI476X_DFS_TRISTATE - put the pin in tristate condition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) * enable 1MOhm pulldown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) * SI476X_DFS_DAUDIO - set the pin to be a part of digital
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) * audio interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) * @dout: - DOUT pin function configuration:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) * SI476X_DOUT_NOOP - do not modify the behaviour
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) * SI476X_DOUT_TRISTATE - put the pin in tristate condition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) * enable 1MOhm pulldown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) * SI476X_DOUT_I2S_OUTPUT - set this pin to be digital out on I2S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) * port 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * SI476X_DOUT_I2S_INPUT - set this pin to be digital in on I2S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) * port 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) * @xout: - XOUT pin function configuration:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) * SI476X_XOUT_NOOP - do not modify the behaviour
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) * SI476X_XOUT_TRISTATE - put the pin in tristate condition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) * enable 1MOhm pulldown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * SI476X_XOUT_I2S_INPUT - set this pin to be digital in on I2S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * port 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) * SI476X_XOUT_MODE_SELECT - set this pin to be the input that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) * selects the mode of the I2S audio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * combiner (analog or HD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) * [SI4761/63/65/67 Only]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) * Function returns 0 on success and negative error code on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) int si476x_core_cmd_dig_audio_pin_cfg(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) enum si476x_dclk_config dclk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) enum si476x_dfs_config dfs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) enum si476x_dout_config dout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) enum si476x_xout_config xout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) u8 resp[CMD_DIG_AUDIO_PIN_CFG_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) const u8 args[CMD_DIG_AUDIO_PIN_CFG_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) PIN_CFG_BYTE(dclk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) PIN_CFG_BYTE(dfs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) PIN_CFG_BYTE(dout),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) PIN_CFG_BYTE(xout),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) return si476x_core_send_command(core, CMD_DIG_AUDIO_PIN_CFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) args, ARRAY_SIZE(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) SI476X_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) EXPORT_SYMBOL_GPL(si476x_core_cmd_dig_audio_pin_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * si476x_cmd_zif_pin_cfg - send 'ZIF_PIN_CFG_COMMAND'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) * @core: - device to send the command to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) * @iqclk: - IQCL pin function configuration:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) * SI476X_IQCLK_NOOP - do not modify the behaviour
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) * SI476X_IQCLK_TRISTATE - put the pin in tristate condition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) * enable 1MOhm pulldown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) * SI476X_IQCLK_IQ - set pin to be a part of I/Q interace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) * in master mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * @iqfs: - IQFS pin function configuration:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * SI476X_IQFS_NOOP - do not modify the behaviour
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) * SI476X_IQFS_TRISTATE - put the pin in tristate condition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) * enable 1MOhm pulldown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) * SI476X_IQFS_IQ - set pin to be a part of I/Q interace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) * in master mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) * @iout: - IOUT pin function configuration:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) * SI476X_IOUT_NOOP - do not modify the behaviour
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) * SI476X_IOUT_TRISTATE - put the pin in tristate condition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) * enable 1MOhm pulldown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * SI476X_IOUT_OUTPUT - set pin to be I out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * @qout: - QOUT pin function configuration:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * SI476X_QOUT_NOOP - do not modify the behaviour
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) * SI476X_QOUT_TRISTATE - put the pin in tristate condition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) * enable 1MOhm pulldown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * SI476X_QOUT_OUTPUT - set pin to be Q out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) * Function returns 0 on success and negative error code on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) int si476x_core_cmd_zif_pin_cfg(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) enum si476x_iqclk_config iqclk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) enum si476x_iqfs_config iqfs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) enum si476x_iout_config iout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) enum si476x_qout_config qout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) u8 resp[CMD_ZIF_PIN_CFG_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) const u8 args[CMD_ZIF_PIN_CFG_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) PIN_CFG_BYTE(iqclk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) PIN_CFG_BYTE(iqfs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) PIN_CFG_BYTE(iout),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) PIN_CFG_BYTE(qout),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) return si476x_core_send_command(core, CMD_ZIF_PIN_CFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) args, ARRAY_SIZE(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) SI476X_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) EXPORT_SYMBOL_GPL(si476x_core_cmd_zif_pin_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) * si476x_cmd_ic_link_gpo_ctl_pin_cfg - send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) * 'IC_LINK_GPIO_CTL_PIN_CFG' comand to the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) * @core: - device to send the command to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) * @icin: - ICIN pin function configuration:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) * SI476X_ICIN_NOOP - do not modify the behaviour
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) * SI476X_ICIN_TRISTATE - put the pin in tristate condition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) * enable 1MOhm pulldown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) * SI476X_ICIN_GPO1_HIGH - set pin to be an output, drive it high
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) * SI476X_ICIN_GPO1_LOW - set pin to be an output, drive it low
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * SI476X_ICIN_IC_LINK - set the pin to be a part of Inter-Chip link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) * @icip: - ICIP pin function configuration:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) * SI476X_ICIP_NOOP - do not modify the behaviour
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) * SI476X_ICIP_TRISTATE - put the pin in tristate condition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) * enable 1MOhm pulldown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) * SI476X_ICIP_GPO1_HIGH - set pin to be an output, drive it high
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) * SI476X_ICIP_GPO1_LOW - set pin to be an output, drive it low
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) * SI476X_ICIP_IC_LINK - set the pin to be a part of Inter-Chip link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) * @icon: - ICON pin function configuration:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) * SI476X_ICON_NOOP - do not modify the behaviour
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) * SI476X_ICON_TRISTATE - put the pin in tristate condition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) * enable 1MOhm pulldown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) * SI476X_ICON_I2S - set the pin to be a part of audio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) * interface in slave mode (DCLK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * SI476X_ICON_IC_LINK - set the pin to be a part of Inter-Chip link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) * @icop: - ICOP pin function configuration:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) * SI476X_ICOP_NOOP - do not modify the behaviour
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * SI476X_ICOP_TRISTATE - put the pin in tristate condition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) * enable 1MOhm pulldown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) * SI476X_ICOP_I2S - set the pin to be a part of audio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) * interface in slave mode (DOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * [Si4761/63/65/67 Only]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * SI476X_ICOP_IC_LINK - set the pin to be a part of Inter-Chip link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) * Function returns 0 on success and negative error code on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) int si476x_core_cmd_ic_link_gpo_ctl_pin_cfg(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) enum si476x_icin_config icin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) enum si476x_icip_config icip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) enum si476x_icon_config icon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) enum si476x_icop_config icop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) u8 resp[CMD_IC_LINK_GPO_CTL_PIN_CFG_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) const u8 args[CMD_IC_LINK_GPO_CTL_PIN_CFG_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) PIN_CFG_BYTE(icin),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) PIN_CFG_BYTE(icip),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) PIN_CFG_BYTE(icon),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) PIN_CFG_BYTE(icop),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) return si476x_core_send_command(core, CMD_IC_LINK_GPO_CTL_PIN_CFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) args, ARRAY_SIZE(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) SI476X_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) EXPORT_SYMBOL_GPL(si476x_core_cmd_ic_link_gpo_ctl_pin_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) * si476x_cmd_ana_audio_pin_cfg - send 'ANA_AUDIO_PIN_CFG' to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) * device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) * @core: - device to send the command to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) * @lrout: - LROUT pin function configuration:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) * SI476X_LROUT_NOOP - do not modify the behaviour
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) * SI476X_LROUT_TRISTATE - put the pin in tristate condition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) * enable 1MOhm pulldown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) * SI476X_LROUT_AUDIO - set pin to be audio output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) * SI476X_LROUT_MPX - set pin to be MPX output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) * Function returns 0 on success and negative error code on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) int si476x_core_cmd_ana_audio_pin_cfg(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) enum si476x_lrout_config lrout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) u8 resp[CMD_ANA_AUDIO_PIN_CFG_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) const u8 args[CMD_ANA_AUDIO_PIN_CFG_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) PIN_CFG_BYTE(lrout),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) return si476x_core_send_command(core, CMD_ANA_AUDIO_PIN_CFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) args, ARRAY_SIZE(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) SI476X_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) EXPORT_SYMBOL_GPL(si476x_core_cmd_ana_audio_pin_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) * si476x_cmd_intb_pin_cfg - send 'INTB_PIN_CFG' command to the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) * @core: - device to send the command to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) * @intb: - INTB pin function configuration:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) * SI476X_INTB_NOOP - do not modify the behaviour
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) * SI476X_INTB_TRISTATE - put the pin in tristate condition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) * enable 1MOhm pulldown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) * SI476X_INTB_DAUDIO - set pin to be a part of digital
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) * audio interface in slave mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) * SI476X_INTB_IRQ - set pin to be an interrupt request line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) * @a1: - A1 pin function configuration:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) * SI476X_A1_NOOP - do not modify the behaviour
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) * SI476X_A1_TRISTATE - put the pin in tristate condition,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) * enable 1MOhm pulldown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) * SI476X_A1_IRQ - set pin to be an interrupt request line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) * Function returns 0 on success and negative error code on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) static int si476x_core_cmd_intb_pin_cfg_a10(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) enum si476x_intb_config intb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) enum si476x_a1_config a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) u8 resp[CMD_INTB_PIN_CFG_A10_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) const u8 args[CMD_INTB_PIN_CFG_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) PIN_CFG_BYTE(intb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) PIN_CFG_BYTE(a1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) return si476x_core_send_command(core, CMD_INTB_PIN_CFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) args, ARRAY_SIZE(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) SI476X_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) static int si476x_core_cmd_intb_pin_cfg_a20(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) enum si476x_intb_config intb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) enum si476x_a1_config a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) u8 resp[CMD_INTB_PIN_CFG_A20_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) const u8 args[CMD_INTB_PIN_CFG_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) PIN_CFG_BYTE(intb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) PIN_CFG_BYTE(a1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) return si476x_core_send_command(core, CMD_INTB_PIN_CFG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) args, ARRAY_SIZE(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) SI476X_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) * si476x_cmd_am_rsq_status - send 'AM_RSQ_STATUS' command to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) * device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) * @core: - device to send the command to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) * @rsqargs: - pointer to a structure containing a group of sub-args
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) * relevant to sending the RSQ status command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) * @report: - all signal quality information retured by the command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) * (if NULL then the output of the command is ignored)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) * Function returns 0 on success and negative error code on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) int si476x_core_cmd_am_rsq_status(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) struct si476x_rsq_status_args *rsqargs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) struct si476x_rsq_status_report *report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) u8 resp[CMD_AM_RSQ_STATUS_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) const u8 args[CMD_AM_RSQ_STATUS_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) rsqargs->rsqack << 3 | rsqargs->attune << 2 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) rsqargs->cancel << 1 | rsqargs->stcack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) err = si476x_core_send_command(core, CMD_AM_RSQ_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) args, ARRAY_SIZE(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) SI476X_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) * Besides getting received signal quality information this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) * command can be used to just acknowledge different interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) * flags in those cases it is useless to copy and parse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) * received data so user can pass NULL, and thus avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) * unnecessary copying.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (!report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) report->snrhint = 0x08 & resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) report->snrlint = 0x04 & resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) report->rssihint = 0x02 & resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) report->rssilint = 0x01 & resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) report->bltf = 0x80 & resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) report->snr_ready = 0x20 & resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) report->rssiready = 0x08 & resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) report->afcrl = 0x02 & resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) report->valid = 0x01 & resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) report->readfreq = get_unaligned_be16(resp + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) report->freqoff = resp[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) report->rssi = resp[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) report->snr = resp[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) report->lassi = resp[9];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) report->hassi = resp[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) report->mult = resp[11];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) report->dev = resp[12];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) EXPORT_SYMBOL_GPL(si476x_core_cmd_am_rsq_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) int si476x_core_cmd_fm_acf_status(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) struct si476x_acf_status_report *report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) u8 resp[CMD_FM_ACF_STATUS_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) const u8 args[CMD_FM_ACF_STATUS_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) if (!report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) err = si476x_core_send_command(core, CMD_FM_ACF_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) args, ARRAY_SIZE(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) SI476X_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) report->blend_int = resp[1] & SI476X_ACF_BLEND_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) report->hblend_int = resp[1] & SI476X_ACF_HIBLEND_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) report->hicut_int = resp[1] & SI476X_ACF_HICUT_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) report->chbw_int = resp[1] & SI476X_ACF_CHBW_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) report->softmute_int = resp[1] & SI476X_ACF_SOFTMUTE_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) report->smute = resp[2] & SI476X_ACF_SMUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) report->smattn = resp[3] & SI476X_ACF_SMATTN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) report->chbw = resp[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) report->hicut = resp[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) report->hiblend = resp[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) report->pilot = resp[7] & SI476X_ACF_PILOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) report->stblend = resp[7] & SI476X_ACF_STBLEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) EXPORT_SYMBOL_GPL(si476x_core_cmd_fm_acf_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) int si476x_core_cmd_am_acf_status(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) struct si476x_acf_status_report *report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) u8 resp[CMD_AM_ACF_STATUS_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) const u8 args[CMD_AM_ACF_STATUS_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (!report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) err = si476x_core_send_command(core, CMD_AM_ACF_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) args, ARRAY_SIZE(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) SI476X_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) report->blend_int = resp[1] & SI476X_ACF_BLEND_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) report->hblend_int = resp[1] & SI476X_ACF_HIBLEND_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) report->hicut_int = resp[1] & SI476X_ACF_HICUT_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) report->chbw_int = resp[1] & SI476X_ACF_CHBW_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) report->softmute_int = resp[1] & SI476X_ACF_SOFTMUTE_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) report->smute = resp[2] & SI476X_ACF_SMUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) report->smattn = resp[3] & SI476X_ACF_SMATTN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) report->chbw = resp[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) report->hicut = resp[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) EXPORT_SYMBOL_GPL(si476x_core_cmd_am_acf_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) * si476x_cmd_fm_seek_start - send 'FM_SEEK_START' command to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) * device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) * @core: - device to send the command to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) * @seekup: - if set the direction of the search is 'up'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) * @wrap: - if set seek wraps when hitting band limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) * This function begins search for a valid station. The station is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) * considered valid when 'FM_VALID_SNR_THRESHOLD' and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) * 'FM_VALID_RSSI_THRESHOLD' and 'FM_VALID_MAX_TUNE_ERROR' criteria
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) * are met.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) } *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) * Function returns 0 on success and negative error code on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) int si476x_core_cmd_fm_seek_start(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) bool seekup, bool wrap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) u8 resp[CMD_FM_SEEK_START_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) const u8 args[CMD_FM_SEEK_START_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) seekup << 3 | wrap << 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) return si476x_cmd_tune_seek_freq(core, CMD_FM_SEEK_START,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) args, sizeof(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) resp, sizeof(resp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) EXPORT_SYMBOL_GPL(si476x_core_cmd_fm_seek_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) * si476x_cmd_fm_rds_status - send 'FM_RDS_STATUS' command to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) * device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) * @core: - device to send the command to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) * @status_only: - if set the data is not removed from RDSFIFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) * RDSFIFOUSED is not decremented and data in all the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) * rest RDS data contains the last valid info received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) * @mtfifo: if set the command clears RDS receive FIFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) * @intack: if set the command clards the RDSINT bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) * @report: - all signal quality information retured by the command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) * (if NULL then the output of the command is ignored)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) * Function returns 0 on success and negative error code on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) int si476x_core_cmd_fm_rds_status(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) bool status_only,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) bool mtfifo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) bool intack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) struct si476x_rds_status_report *report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) u8 resp[CMD_FM_RDS_STATUS_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) const u8 args[CMD_FM_RDS_STATUS_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) status_only << 2 | mtfifo << 1 | intack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) err = si476x_core_send_command(core, CMD_FM_RDS_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) args, ARRAY_SIZE(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) SI476X_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) * Besides getting RDS status information this command can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) * used to just acknowledge different interrupt flags in those
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) * cases it is useless to copy and parse received data so user
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) * can pass NULL, and thus avoid unnecessary copying.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (err < 0 || report == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) report->rdstpptyint = 0x10 & resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) report->rdspiint = 0x08 & resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) report->rdssyncint = 0x02 & resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) report->rdsfifoint = 0x01 & resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) report->tpptyvalid = 0x10 & resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) report->pivalid = 0x08 & resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) report->rdssync = 0x02 & resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) report->rdsfifolost = 0x01 & resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) report->tp = 0x20 & resp[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) report->pty = 0x1f & resp[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) report->pi = get_unaligned_be16(resp + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) report->rdsfifoused = resp[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) report->ble[V4L2_RDS_BLOCK_A] = 0xc0 & resp[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) report->ble[V4L2_RDS_BLOCK_B] = 0x30 & resp[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) report->ble[V4L2_RDS_BLOCK_C] = 0x0c & resp[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) report->ble[V4L2_RDS_BLOCK_D] = 0x03 & resp[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) report->rds[V4L2_RDS_BLOCK_A].block = V4L2_RDS_BLOCK_A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) report->rds[V4L2_RDS_BLOCK_A].msb = resp[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) report->rds[V4L2_RDS_BLOCK_A].lsb = resp[9];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) report->rds[V4L2_RDS_BLOCK_B].block = V4L2_RDS_BLOCK_B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) report->rds[V4L2_RDS_BLOCK_B].msb = resp[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) report->rds[V4L2_RDS_BLOCK_B].lsb = resp[11];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) report->rds[V4L2_RDS_BLOCK_C].block = V4L2_RDS_BLOCK_C;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) report->rds[V4L2_RDS_BLOCK_C].msb = resp[12];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) report->rds[V4L2_RDS_BLOCK_C].lsb = resp[13];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) report->rds[V4L2_RDS_BLOCK_D].block = V4L2_RDS_BLOCK_D;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) report->rds[V4L2_RDS_BLOCK_D].msb = resp[14];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) report->rds[V4L2_RDS_BLOCK_D].lsb = resp[15];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) EXPORT_SYMBOL_GPL(si476x_core_cmd_fm_rds_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) int si476x_core_cmd_fm_rds_blockcount(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) bool clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) struct si476x_rds_blockcount_report *report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) u8 resp[CMD_FM_RDS_BLOCKCOUNT_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) const u8 args[CMD_FM_RDS_BLOCKCOUNT_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (!report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) err = si476x_core_send_command(core, CMD_FM_RDS_BLOCKCOUNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) args, ARRAY_SIZE(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) SI476X_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) report->expected = get_unaligned_be16(resp + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) report->received = get_unaligned_be16(resp + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) report->uncorrectable = get_unaligned_be16(resp + 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) EXPORT_SYMBOL_GPL(si476x_core_cmd_fm_rds_blockcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) int si476x_core_cmd_fm_phase_diversity(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) enum si476x_phase_diversity_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) u8 resp[CMD_FM_PHASE_DIVERSITY_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) const u8 args[CMD_FM_PHASE_DIVERSITY_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) mode & 0x07,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) return si476x_core_send_command(core, CMD_FM_PHASE_DIVERSITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) args, ARRAY_SIZE(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) SI476X_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) EXPORT_SYMBOL_GPL(si476x_core_cmd_fm_phase_diversity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) * si476x_core_cmd_fm_phase_div_status() - get the phase diversity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) * status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) * @core: si476x device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) * NOTE caller must hold core lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) * Function returns the value of the status bit in case of success and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) * negative error code in case of failre.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) int si476x_core_cmd_fm_phase_div_status(struct si476x_core *core)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) u8 resp[CMD_FM_PHASE_DIV_STATUS_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) err = si476x_core_send_command(core, CMD_FM_PHASE_DIV_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) SI476X_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) return (err < 0) ? err : resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) EXPORT_SYMBOL_GPL(si476x_core_cmd_fm_phase_div_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) * si476x_cmd_am_seek_start - send 'FM_SEEK_START' command to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) * device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) * @core: - device to send the command to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) * @seekup: - if set the direction of the search is 'up'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) * @wrap: - if set seek wraps when hitting band limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) * This function begins search for a valid station. The station is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) * considered valid when 'FM_VALID_SNR_THRESHOLD' and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) * 'FM_VALID_RSSI_THRESHOLD' and 'FM_VALID_MAX_TUNE_ERROR' criteria
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) * are met.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) * Function returns 0 on success and negative error code on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) int si476x_core_cmd_am_seek_start(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) bool seekup, bool wrap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) u8 resp[CMD_AM_SEEK_START_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) const u8 args[CMD_AM_SEEK_START_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) seekup << 3 | wrap << 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) return si476x_cmd_tune_seek_freq(core, CMD_AM_SEEK_START,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) args, sizeof(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) resp, sizeof(resp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) EXPORT_SYMBOL_GPL(si476x_core_cmd_am_seek_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) static int si476x_core_cmd_power_up_a10(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) struct si476x_power_up_args *puargs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) u8 resp[CMD_POWER_UP_A10_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) const bool intsel = (core->pinmux.a1 == SI476X_A1_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) const bool ctsen = (core->client->irq != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) const u8 args[CMD_POWER_UP_A10_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 0xF7, /* Reserved, always 0xF7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 0x3F & puargs->xcload, /* First two bits are reserved to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) * zeros */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) ctsen << 7 | intsel << 6 | 0x07, /* Last five bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) * are reserved to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) * be written as 0x7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) puargs->func << 4 | puargs->freq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 0x11, /* Reserved, always 0x11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) return si476x_core_send_command(core, CMD_POWER_UP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) args, ARRAY_SIZE(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) SI476X_TIMEOUT_POWER_UP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) static int si476x_core_cmd_power_up_a20(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) struct si476x_power_up_args *puargs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) u8 resp[CMD_POWER_UP_A20_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) const bool intsel = (core->pinmux.a1 == SI476X_A1_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) const bool ctsen = (core->client->irq != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) const u8 args[CMD_POWER_UP_A20_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) puargs->ibias6x << 7 | puargs->xstart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 0x3F & puargs->xcload, /* First two bits are reserved to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) * zeros */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) ctsen << 7 | intsel << 6 | puargs->fastboot << 5 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) puargs->xbiashc << 3 | puargs->xbias,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) puargs->func << 4 | puargs->freq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 0x10 | puargs->xmode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) return si476x_core_send_command(core, CMD_POWER_UP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) args, ARRAY_SIZE(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) SI476X_TIMEOUT_POWER_UP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) static int si476x_core_cmd_power_down_a10(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) struct si476x_power_down_args *pdargs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) u8 resp[CMD_POWER_DOWN_A10_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) return si476x_core_send_command(core, CMD_POWER_DOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) SI476X_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) static int si476x_core_cmd_power_down_a20(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) struct si476x_power_down_args *pdargs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) u8 resp[CMD_POWER_DOWN_A20_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) const u8 args[CMD_POWER_DOWN_A20_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) pdargs->xosc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) return si476x_core_send_command(core, CMD_POWER_DOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) args, ARRAY_SIZE(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) SI476X_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) static int si476x_core_cmd_am_tune_freq_a10(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) struct si476x_tune_freq_args *tuneargs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) const int am_freq = tuneargs->freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) u8 resp[CMD_AM_TUNE_FREQ_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) const u8 args[CMD_AM_TUNE_FREQ_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) (tuneargs->hd << 6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) msb(am_freq),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) lsb(am_freq),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) return si476x_cmd_tune_seek_freq(core, CMD_AM_TUNE_FREQ, args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) sizeof(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) resp, sizeof(resp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) static int si476x_core_cmd_am_tune_freq_a20(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) struct si476x_tune_freq_args *tuneargs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) const int am_freq = tuneargs->freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) u8 resp[CMD_AM_TUNE_FREQ_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) const u8 args[CMD_AM_TUNE_FREQ_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) (tuneargs->zifsr << 6) | (tuneargs->injside & 0x03),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) msb(am_freq),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) lsb(am_freq),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) return si476x_cmd_tune_seek_freq(core, CMD_AM_TUNE_FREQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) args, sizeof(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) resp, sizeof(resp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) static int si476x_core_cmd_fm_rsq_status_a10(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) struct si476x_rsq_status_args *rsqargs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) struct si476x_rsq_status_report *report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) u8 resp[CMD_FM_RSQ_STATUS_A10_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) const u8 args[CMD_FM_RSQ_STATUS_A10_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) rsqargs->rsqack << 3 | rsqargs->attune << 2 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) rsqargs->cancel << 1 | rsqargs->stcack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) err = si476x_core_send_command(core, CMD_FM_RSQ_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) args, ARRAY_SIZE(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) SI476X_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) * Besides getting received signal quality information this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) * command can be used to just acknowledge different interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) * flags in those cases it is useless to copy and parse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) * received data so user can pass NULL, and thus avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) * unnecessary copying.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) if (err < 0 || report == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) report->multhint = 0x80 & resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) report->multlint = 0x40 & resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) report->snrhint = 0x08 & resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) report->snrlint = 0x04 & resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) report->rssihint = 0x02 & resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) report->rssilint = 0x01 & resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) report->bltf = 0x80 & resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) report->snr_ready = 0x20 & resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) report->rssiready = 0x08 & resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) report->afcrl = 0x02 & resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) report->valid = 0x01 & resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) report->readfreq = get_unaligned_be16(resp + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) report->freqoff = resp[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) report->rssi = resp[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) report->snr = resp[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) report->lassi = resp[9];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) report->hassi = resp[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) report->mult = resp[11];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) report->dev = resp[12];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) report->readantcap = get_unaligned_be16(resp + 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) report->assi = resp[15];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) report->usn = resp[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) static int si476x_core_cmd_fm_rsq_status_a20(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) struct si476x_rsq_status_args *rsqargs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) struct si476x_rsq_status_report *report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) u8 resp[CMD_FM_RSQ_STATUS_A10_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) const u8 args[CMD_FM_RSQ_STATUS_A30_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) rsqargs->primary << 4 | rsqargs->rsqack << 3 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) rsqargs->attune << 2 | rsqargs->cancel << 1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) rsqargs->stcack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) err = si476x_core_send_command(core, CMD_FM_RSQ_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) args, ARRAY_SIZE(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) SI476X_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) * Besides getting received signal quality information this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) * command can be used to just acknowledge different interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) * flags in those cases it is useless to copy and parse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) * received data so user can pass NULL, and thus avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) * unnecessary copying.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) if (err < 0 || report == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) report->multhint = 0x80 & resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) report->multlint = 0x40 & resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) report->snrhint = 0x08 & resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) report->snrlint = 0x04 & resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) report->rssihint = 0x02 & resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) report->rssilint = 0x01 & resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) report->bltf = 0x80 & resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) report->snr_ready = 0x20 & resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) report->rssiready = 0x08 & resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) report->afcrl = 0x02 & resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) report->valid = 0x01 & resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) report->readfreq = get_unaligned_be16(resp + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) report->freqoff = resp[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) report->rssi = resp[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) report->snr = resp[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) report->lassi = resp[9];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) report->hassi = resp[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) report->mult = resp[11];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) report->dev = resp[12];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) report->readantcap = get_unaligned_be16(resp + 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) report->assi = resp[15];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) report->usn = resp[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) static int si476x_core_cmd_fm_rsq_status_a30(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) struct si476x_rsq_status_args *rsqargs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) struct si476x_rsq_status_report *report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) u8 resp[CMD_FM_RSQ_STATUS_A30_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) const u8 args[CMD_FM_RSQ_STATUS_A30_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) rsqargs->primary << 4 | rsqargs->rsqack << 3 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) rsqargs->attune << 2 | rsqargs->cancel << 1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) rsqargs->stcack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) err = si476x_core_send_command(core, CMD_FM_RSQ_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) args, ARRAY_SIZE(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) SI476X_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) * Besides getting received signal quality information this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) * command can be used to just acknowledge different interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) * flags in those cases it is useless to copy and parse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) * received data so user can pass NULL, and thus avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) * unnecessary copying.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) if (err < 0 || report == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) report->multhint = 0x80 & resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) report->multlint = 0x40 & resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) report->snrhint = 0x08 & resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) report->snrlint = 0x04 & resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) report->rssihint = 0x02 & resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) report->rssilint = 0x01 & resp[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) report->bltf = 0x80 & resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) report->snr_ready = 0x20 & resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) report->rssiready = 0x08 & resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) report->injside = 0x04 & resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) report->afcrl = 0x02 & resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) report->valid = 0x01 & resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) report->readfreq = get_unaligned_be16(resp + 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) report->freqoff = resp[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) report->rssi = resp[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) report->snr = resp[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) report->issi = resp[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) report->lassi = resp[9];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) report->hassi = resp[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) report->mult = resp[11];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) report->dev = resp[12];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) report->readantcap = get_unaligned_be16(resp + 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) report->assi = resp[15];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) report->usn = resp[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) report->pilotdev = resp[17];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) report->rdsdev = resp[18];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) report->assidev = resp[19];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) report->strongdev = resp[20];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) report->rdspi = get_unaligned_be16(resp + 21);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) static int si476x_core_cmd_fm_tune_freq_a10(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) struct si476x_tune_freq_args *tuneargs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) u8 resp[CMD_FM_TUNE_FREQ_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) const u8 args[CMD_FM_TUNE_FREQ_A10_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) (tuneargs->hd << 6) | (tuneargs->tunemode << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) | (tuneargs->smoothmetrics << 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) msb(tuneargs->freq),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) lsb(tuneargs->freq),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) msb(tuneargs->antcap),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) lsb(tuneargs->antcap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) return si476x_cmd_tune_seek_freq(core, CMD_FM_TUNE_FREQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) args, sizeof(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) resp, sizeof(resp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) static int si476x_core_cmd_fm_tune_freq_a20(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) struct si476x_tune_freq_args *tuneargs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) u8 resp[CMD_FM_TUNE_FREQ_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) const u8 args[CMD_FM_TUNE_FREQ_A20_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) (tuneargs->hd << 6) | (tuneargs->tunemode << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) | (tuneargs->smoothmetrics << 2) | (tuneargs->injside),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) msb(tuneargs->freq),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) lsb(tuneargs->freq),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) return si476x_cmd_tune_seek_freq(core, CMD_FM_TUNE_FREQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) args, sizeof(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) resp, sizeof(resp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) static int si476x_core_cmd_agc_status_a20(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) struct si476x_agc_status_report *report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) u8 resp[CMD_AGC_STATUS_NRESP_A20];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) if (!report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) err = si476x_core_send_command(core, CMD_AGC_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) SI476X_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) report->mxhi = resp[1] & SI476X_AGC_MXHI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) report->mxlo = resp[1] & SI476X_AGC_MXLO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) report->lnahi = resp[1] & SI476X_AGC_LNAHI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) report->lnalo = resp[1] & SI476X_AGC_LNALO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) report->fmagc1 = resp[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) report->fmagc2 = resp[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) report->pgagain = resp[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) report->fmwblang = resp[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) static int si476x_core_cmd_agc_status_a10(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) struct si476x_agc_status_report *report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) u8 resp[CMD_AGC_STATUS_NRESP_A10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) if (!report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) err = si476x_core_send_command(core, CMD_AGC_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) SI476X_DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) report->mxhi = resp[1] & SI476X_AGC_MXHI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) report->mxlo = resp[1] & SI476X_AGC_MXLO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) report->lnahi = resp[1] & SI476X_AGC_LNAHI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) report->lnalo = resp[1] & SI476X_AGC_LNALO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) typedef int (*tune_freq_func_t) (struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) struct si476x_tune_freq_args *tuneargs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) int (*power_up)(struct si476x_core *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) struct si476x_power_up_args *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) int (*power_down)(struct si476x_core *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) struct si476x_power_down_args *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) tune_freq_func_t fm_tune_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) tune_freq_func_t am_tune_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) int (*fm_rsq_status)(struct si476x_core *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) struct si476x_rsq_status_args *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) struct si476x_rsq_status_report *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) int (*agc_status)(struct si476x_core *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) struct si476x_agc_status_report *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) int (*intb_pin_cfg)(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) enum si476x_intb_config intb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) enum si476x_a1_config a1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) } si476x_cmds_vtable[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) [SI476X_REVISION_A10] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) .power_up = si476x_core_cmd_power_up_a10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) .power_down = si476x_core_cmd_power_down_a10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) .fm_tune_freq = si476x_core_cmd_fm_tune_freq_a10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) .am_tune_freq = si476x_core_cmd_am_tune_freq_a10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) .fm_rsq_status = si476x_core_cmd_fm_rsq_status_a10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) .agc_status = si476x_core_cmd_agc_status_a10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) .intb_pin_cfg = si476x_core_cmd_intb_pin_cfg_a10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) [SI476X_REVISION_A20] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) .power_up = si476x_core_cmd_power_up_a20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) .power_down = si476x_core_cmd_power_down_a20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) .fm_tune_freq = si476x_core_cmd_fm_tune_freq_a20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) .am_tune_freq = si476x_core_cmd_am_tune_freq_a20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) .fm_rsq_status = si476x_core_cmd_fm_rsq_status_a20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) .agc_status = si476x_core_cmd_agc_status_a20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) .intb_pin_cfg = si476x_core_cmd_intb_pin_cfg_a20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) [SI476X_REVISION_A30] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) .power_up = si476x_core_cmd_power_up_a20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) .power_down = si476x_core_cmd_power_down_a20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) .fm_tune_freq = si476x_core_cmd_fm_tune_freq_a20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) .am_tune_freq = si476x_core_cmd_am_tune_freq_a20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) .fm_rsq_status = si476x_core_cmd_fm_rsq_status_a30,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) .agc_status = si476x_core_cmd_agc_status_a20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) .intb_pin_cfg = si476x_core_cmd_intb_pin_cfg_a20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) int si476x_core_cmd_power_up(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) struct si476x_power_up_args *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) BUG_ON(core->revision > SI476X_REVISION_A30 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) core->revision == -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) return si476x_cmds_vtable[core->revision].power_up(core, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) EXPORT_SYMBOL_GPL(si476x_core_cmd_power_up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) int si476x_core_cmd_power_down(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) struct si476x_power_down_args *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) BUG_ON(core->revision > SI476X_REVISION_A30 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) core->revision == -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) return si476x_cmds_vtable[core->revision].power_down(core, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) EXPORT_SYMBOL_GPL(si476x_core_cmd_power_down);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) int si476x_core_cmd_fm_tune_freq(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) struct si476x_tune_freq_args *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) BUG_ON(core->revision > SI476X_REVISION_A30 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) core->revision == -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) return si476x_cmds_vtable[core->revision].fm_tune_freq(core, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) EXPORT_SYMBOL_GPL(si476x_core_cmd_fm_tune_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) int si476x_core_cmd_am_tune_freq(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) struct si476x_tune_freq_args *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) BUG_ON(core->revision > SI476X_REVISION_A30 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) core->revision == -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) return si476x_cmds_vtable[core->revision].am_tune_freq(core, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) EXPORT_SYMBOL_GPL(si476x_core_cmd_am_tune_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) int si476x_core_cmd_fm_rsq_status(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) struct si476x_rsq_status_args *args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) struct si476x_rsq_status_report *report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) BUG_ON(core->revision > SI476X_REVISION_A30 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) core->revision == -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) return si476x_cmds_vtable[core->revision].fm_rsq_status(core, args,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) report);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) EXPORT_SYMBOL_GPL(si476x_core_cmd_fm_rsq_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) int si476x_core_cmd_agc_status(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) struct si476x_agc_status_report *report)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) BUG_ON(core->revision > SI476X_REVISION_A30 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) core->revision == -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) return si476x_cmds_vtable[core->revision].agc_status(core, report);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) EXPORT_SYMBOL_GPL(si476x_core_cmd_agc_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) int si476x_core_cmd_intb_pin_cfg(struct si476x_core *core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) enum si476x_intb_config intb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) enum si476x_a1_config a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) BUG_ON(core->revision > SI476X_REVISION_A30 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) core->revision == -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) return si476x_cmds_vtable[core->revision].intb_pin_cfg(core, intb, a1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) EXPORT_SYMBOL_GPL(si476x_core_cmd_intb_pin_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) MODULE_DESCRIPTION("API for command exchange for si476x");