Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * drivers/media/radio/si4713-i2c.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Silicon Labs Si4713 FM Radio Transmitter I2C commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * Copyright (c) 2009 Nokia Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * Contact: Eduardo Valentin <eduardo.valentin@nokia.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <media/v4l2-device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <media/v4l2-ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <media/v4l2-common.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include "si4713.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) /* module parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) static int debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) module_param(debug, int, S_IRUGO | S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) MODULE_PARM_DESC(debug, "Debug level (0 - 2)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) MODULE_AUTHOR("Eduardo Valentin <eduardo.valentin@nokia.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) MODULE_DESCRIPTION("I2C driver for Si4713 FM Radio Transmitter");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) MODULE_VERSION("0.0.1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #define DEFAULT_RDS_PI			0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #define DEFAULT_RDS_PTY			0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #define DEFAULT_RDS_DEVIATION		0x00C8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #define DEFAULT_RDS_PS_REPEAT_COUNT	0x0003
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #define DEFAULT_LIMITER_RTIME		0x1392
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #define DEFAULT_LIMITER_DEV		0x102CA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #define DEFAULT_PILOT_FREQUENCY		0x4A38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #define DEFAULT_PILOT_DEVIATION		0x1A5E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #define DEFAULT_ACOMP_ATIME		0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #define DEFAULT_ACOMP_RTIME		0xF4240L
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #define DEFAULT_ACOMP_GAIN		0x0F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #define DEFAULT_ACOMP_THRESHOLD		(-0x28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #define DEFAULT_MUTE			0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #define DEFAULT_POWER_LEVEL		88
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #define DEFAULT_FREQUENCY		8800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #define DEFAULT_PREEMPHASIS		FMPE_EU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #define DEFAULT_TUNE_RNL		0xFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #define to_si4713_device(sd)	container_of(sd, struct si4713_device, sd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) /* frequency domain transformation (using times 10 to avoid floats) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #define FREQDEV_UNIT	100000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #define FREQV4L2_MULTI	625
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #define si4713_to_v4l2(f)	((f * FREQDEV_UNIT) / FREQV4L2_MULTI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #define v4l2_to_si4713(f)	((f * FREQV4L2_MULTI) / FREQDEV_UNIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #define FREQ_RANGE_LOW			7600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) #define FREQ_RANGE_HIGH			10800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) #define MAX_ARGS 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) #define RDS_BLOCK			8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) #define RDS_BLOCK_CLEAR			0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) #define RDS_BLOCK_LOAD			0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) #define RDS_RADIOTEXT_2A		0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) #define RDS_RADIOTEXT_BLK_SIZE		4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) #define RDS_RADIOTEXT_INDEX_MAX		0x0F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) #define RDS_CARRIAGE_RETURN		0x0D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) #define rds_ps_nblocks(len)	((len / RDS_BLOCK) + (len % RDS_BLOCK ? 1 : 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) #define get_status_bit(p, b, m)	(((p) & (m)) >> (b))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) #define set_bits(p, v, b, m)	(((p) & ~(m)) | ((v) << (b)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) #define ATTACK_TIME_UNIT	500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) #define POWER_OFF			0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) #define POWER_ON			0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) #define msb(x)                  ((u8)((u16) x >> 8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) #define lsb(x)                  ((u8)((u16) x &  0x00FF))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) #define compose_u16(msb, lsb)	(((u16)msb << 8) | lsb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) #define check_command_failed(status)	(!(status & SI4713_CTS) || \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 					(status & SI4713_ERR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) /* mute definition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) #define set_mute(p)	((p & 1) | ((p & 1) << 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) #define DBG_BUFFER(device, message, buffer, size)			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	{								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 		int i;							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 		char str[(size)*5];					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 		for (i = 0; i < size; i++)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 			sprintf(str + i * 5, " 0x%02x", buffer[i]);	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 		v4l2_dbg(2, debug, device, "%s:%s\n", message, str);	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) #define DBG_BUFFER(device, message, buffer, size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105)  * Values for limiter release time (sorted by second column)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106)  *	device	release
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107)  *	value	time (us)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) static long limiter_times[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	2000,	250,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	1000,	500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	510,	1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	255,	2000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	170,	3000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	127,	4020,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	102,	5010,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	85,	6020,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	73,	7010,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	64,	7990,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	57,	8970,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	51,	10030,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	25,	20470,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	17,	30110,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	13,	39380,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	10,	51190,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	8,	63690,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	7,	73140,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	6,	85330,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	5,	102390,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133)  * Values for audio compression release time (sorted by second column)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134)  *	device	release
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135)  *	value	time (us)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) static unsigned long acomp_rtimes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	0,	100000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	1,	200000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	2,	350000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	3,	525000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	4,	1000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146)  * Values for preemphasis (sorted by second column)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147)  *	device	preemphasis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148)  *	value	value (v4l2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) static unsigned long preemphasis_values[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	FMPE_DISABLED,	V4L2_PREEMPHASIS_DISABLED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	FMPE_EU,	V4L2_PREEMPHASIS_50_uS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	FMPE_USA,	V4L2_PREEMPHASIS_75_uS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) static int usecs_to_dev(unsigned long usecs, unsigned long const array[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 			int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	int rval = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	for (i = 0; i < size / 2; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 		if (array[(i * 2) + 1] >= usecs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 			rval = array[i * 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	return rval;
^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) /* si4713_handler: IRQ handler, just complete work */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) static irqreturn_t si4713_handler(int irq, void *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	struct si4713_device *sdev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	v4l2_dbg(2, debug, &sdev->sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 			"%s: sending signal to completion work.\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	complete(&sdev->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184)  * si4713_send_command - sends a command to si4713 and waits its response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185)  * @sdev: si4713_device structure for the device we are communicating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186)  * @command: command id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187)  * @args: command arguments we are sending (up to 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188)  * @argn: actual size of @args
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189)  * @response: buffer to place the expected response from the device (up to 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190)  * @respn: actual size of @response
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191)  * @usecs: amount of time to wait before reading the response (in usecs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) static int si4713_send_command(struct si4713_device *sdev, const u8 command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 				const u8 args[], const int argn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 				u8 response[], const int respn, const int usecs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	struct i2c_client *client = v4l2_get_subdevdata(&sdev->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	unsigned long until_jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	u8 data1[MAX_ARGS + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	if (!client->adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	/* First send the command and its arguments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	data1[0] = command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	memcpy(data1 + 1, args, argn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	DBG_BUFFER(&sdev->sd, "Parameters", data1, argn + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	err = i2c_master_send(client, data1, argn + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	if (err != argn + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 		v4l2_err(&sdev->sd, "Error while sending command 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 			command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 		return err < 0 ? err : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	until_jiffies = jiffies + usecs_to_jiffies(usecs) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	/* Wait response from interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	if (client->irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 		if (!wait_for_completion_timeout(&sdev->work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 				usecs_to_jiffies(usecs) + 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 			v4l2_warn(&sdev->sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 				"(%s) Device took too much time to answer.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 				__func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 		err = i2c_master_recv(client, response, respn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 		if (err != respn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 			v4l2_err(&sdev->sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 				"Error %d while reading response for command 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 				err, command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 			return err < 0 ? err : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 		DBG_BUFFER(&sdev->sd, "Response", response, respn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 		if (!check_command_failed(response[0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 		if (client->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 			return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 		if (usecs <= 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 			usleep_range(usecs, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 			usleep_range(1000, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	} while (time_is_after_jiffies(until_jiffies));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253)  * si4713_read_property - reads a si4713 property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254)  * @sdev: si4713_device structure for the device we are communicating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255)  * @prop: property identification number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256)  * @pv: property value to be returned on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) static int si4713_read_property(struct si4713_device *sdev, u16 prop, u32 *pv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	u8 val[SI4713_GET_PROP_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	 *	.First byte = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	 *	.Second byte = property's MSB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	 *	.Third byte = property's LSB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	const u8 args[SI4713_GET_PROP_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 		0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 		msb(prop),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 		lsb(prop),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	err = si4713_send_command(sdev, SI4713_CMD_GET_PROPERTY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 				  args, ARRAY_SIZE(args), val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 				  ARRAY_SIZE(val), DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	*pv = compose_u16(val[2], val[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	v4l2_dbg(1, debug, &sdev->sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 			"%s: property=0x%02x value=0x%02x status=0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 			__func__, prop, *pv, val[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290)  * si4713_write_property - modifies a si4713 property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291)  * @sdev: si4713_device structure for the device we are communicating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292)  * @prop: property identification number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293)  * @val: new value for that property
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) static int si4713_write_property(struct si4713_device *sdev, u16 prop, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	u8 resp[SI4713_SET_PROP_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	 *	.First byte = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	 *	.Second byte = property's MSB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	 *	.Third byte = property's LSB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	 *	.Fourth byte = value's MSB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	 *	.Fifth byte = value's LSB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	const u8 args[SI4713_SET_PROP_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 		0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 		msb(prop),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 		lsb(prop),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 		msb(val),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 		lsb(val),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	rval = si4713_send_command(sdev, SI4713_CMD_SET_PROPERTY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 					args, ARRAY_SIZE(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 					resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 					DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	if (rval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	v4l2_dbg(1, debug, &sdev->sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 			"%s: property=0x%02x value=0x%02x status=0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 			__func__, prop, val, resp[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	 * As there is no command response for SET_PROPERTY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	 * wait Tcomp time to finish before proceed, in order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	 * to have property properly set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	msleep(TIMEOUT_SET_PROPERTY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337)  * si4713_powerup - Powers the device up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338)  * @sdev: si4713_device structure for the device we are communicating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) static int si4713_powerup(struct si4713_device *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	struct i2c_client *client = v4l2_get_subdevdata(&sdev->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	u8 resp[SI4713_PWUP_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	 *	.First byte = Enabled interrupts and boot function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	 *	.Second byte = Input operation mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	u8 args[SI4713_PWUP_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 		SI4713_PWUP_GPO2OEN | SI4713_PWUP_FUNC_TX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 		SI4713_PWUP_OPMOD_ANALOG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	if (sdev->power_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	if (sdev->vdd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 		err = regulator_enable(sdev->vdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 			v4l2_err(&sdev->sd, "Failed to enable vdd: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	if (sdev->vio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 		err = regulator_enable(sdev->vio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 			v4l2_err(&sdev->sd, "Failed to enable vio: %d\n", err);
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	if (sdev->gpio_reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 		udelay(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 		gpiod_set_value(sdev->gpio_reset, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	if (client->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 		args[0] |= SI4713_PWUP_CTSIEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	err = si4713_send_command(sdev, SI4713_CMD_POWER_UP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 					args, ARRAY_SIZE(args),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 					resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 					TIMEOUT_POWER_UP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 		v4l2_dbg(1, debug, &sdev->sd, "Powerup response: 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 				resp[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 		v4l2_dbg(1, debug, &sdev->sd, "Device in power up mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 		sdev->power_state = POWER_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 		if (client->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 			err = si4713_write_property(sdev, SI4713_GPO_IEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 						SI4713_STC_INT | SI4713_CTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	gpiod_set_value(sdev->gpio_reset, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	if (sdev->vdd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 		err = regulator_disable(sdev->vdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 			v4l2_err(&sdev->sd, "Failed to disable vdd: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	if (sdev->vio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 		err = regulator_disable(sdev->vio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 			v4l2_err(&sdev->sd, "Failed to disable vio: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416)  * si4713_powerdown - Powers the device down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417)  * @sdev: si4713_device structure for the device we are communicating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) static int si4713_powerdown(struct si4713_device *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	u8 resp[SI4713_PWDN_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	if (!sdev->power_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	err = si4713_send_command(sdev, SI4713_CMD_POWER_DOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 					NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 					resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 					DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 		v4l2_dbg(1, debug, &sdev->sd, "Power down response: 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 				resp[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 		v4l2_dbg(1, debug, &sdev->sd, "Device in reset mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 		if (sdev->gpio_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 			gpiod_set_value(sdev->gpio_reset, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 		if (sdev->vdd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 			err = regulator_disable(sdev->vdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 			if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 				v4l2_err(&sdev->sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 					"Failed to disable vdd: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 			}
^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) 		if (sdev->vio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 			err = regulator_disable(sdev->vio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 			if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 				v4l2_err(&sdev->sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 					"Failed to disable vio: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 		sdev->power_state = POWER_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461)  * si4713_checkrev - Checks if we are treating a device with the correct rev.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462)  * @sdev: si4713_device structure for the device we are communicating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) static int si4713_checkrev(struct si4713_device *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	struct i2c_client *client = v4l2_get_subdevdata(&sdev->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	u8 resp[SI4713_GETREV_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	rval = si4713_send_command(sdev, SI4713_CMD_GET_REV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 					NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 					resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 					DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	if (rval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	if (resp[1] == SI4713_PRODUCT_NUMBER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 		v4l2_info(&sdev->sd, "chip found @ 0x%02x (%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 				client->addr << 1, client->adapter->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 		v4l2_err(&sdev->sd, "Invalid product number 0x%X\n", resp[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 		rval = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489)  * si4713_wait_stc - Waits STC interrupt and clears status bits. Useful
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490)  *		     for TX_TUNE_POWER, TX_TUNE_FREQ and TX_TUNE_MEAS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491)  * @sdev: si4713_device structure for the device we are communicating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492)  * @usecs: timeout to wait for STC interrupt signal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) static int si4713_wait_stc(struct si4713_device *sdev, const int usecs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	struct i2c_client *client = v4l2_get_subdevdata(&sdev->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	u8 resp[SI4713_GET_STATUS_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	unsigned long start_jiffies = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	if (client->irq &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	    !wait_for_completion_timeout(&sdev->work, usecs_to_jiffies(usecs) + 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 		v4l2_warn(&sdev->sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 			"(%s) Device took too much time to answer.\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 		/* Clear status bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 		err = si4713_send_command(sdev, SI4713_CMD_GET_INT_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 				NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 				resp, ARRAY_SIZE(resp),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 				DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 		/* The USB device returns errors when it waits for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 		 * STC bit to be set. Hence polling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 		if (err >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 			v4l2_dbg(1, debug, &sdev->sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 				"%s: status bits: 0x%02x\n", __func__, resp[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 			if (resp[0] & SI4713_STC_INT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 		if (jiffies_to_usecs(jiffies - start_jiffies) > usecs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 			return err < 0 ? err : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 		/* We sleep here for 3-4 ms in order to avoid flooding the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 		 * with USB requests. The si4713 USB driver was developed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 		 * by reverse engineering the Windows USB driver. The windows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		 * driver also has a ~2.5 ms delay between responses. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 		usleep_range(3000, 4000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532)  * si4713_tx_tune_freq - Sets the state of the RF carrier and sets the tuning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533)  *			frequency between 76 and 108 MHz in 10 kHz units and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534)  *			steps of 50 kHz.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535)  * @sdev: si4713_device structure for the device we are communicating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536)  * @frequency: desired frequency (76 - 108 MHz, unit 10 KHz, step 50 kHz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) static int si4713_tx_tune_freq(struct si4713_device *sdev, u16 frequency)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	u8 val[SI4713_TXFREQ_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	 *	.First byte = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	 *	.Second byte = frequency's MSB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	 *	.Third byte = frequency's LSB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	const u8 args[SI4713_TXFREQ_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 		0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 		msb(frequency),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 		lsb(frequency),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	err = si4713_send_command(sdev, SI4713_CMD_TX_TUNE_FREQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 				  args, ARRAY_SIZE(args), val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 				  ARRAY_SIZE(val), DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	v4l2_dbg(1, debug, &sdev->sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 			"%s: frequency=0x%02x status=0x%02x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 			frequency, val[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	err = si4713_wait_stc(sdev, TIMEOUT_TX_TUNE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	return compose_u16(args[1], args[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572)  * si4713_tx_tune_power - Sets the RF voltage level between 88 and 120 dBuV in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573)  *			1 dB units. A value of 0x00 indicates off. The command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574)  *			also sets the antenna tuning capacitance. A value of 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575)  *			indicates autotuning, and a value of 1 - 191 indicates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576)  *			a manual override, which results in a tuning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577)  *			capacitance of 0.25 pF x @antcap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578)  * @sdev: si4713_device structure for the device we are communicating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579)  * @power: tuning power (88 - 120 dBuV, unit/step 1 dB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580)  * @antcap: value of antenna tuning capacitor (0 - 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) static int si4713_tx_tune_power(struct si4713_device *sdev, u8 power,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 				u8 antcap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	u8 val[SI4713_TXPWR_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	 *	.First byte = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	 *	.Second byte = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	 *	.Third byte = power
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	 *	.Fourth byte = antcap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	u8 args[SI4713_TXPWR_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 		0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 		0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 		power,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 		antcap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	/* Map power values 1-87 to MIN_POWER (88) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	if (power > 0 && power < SI4713_MIN_POWER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 		args[2] = power = SI4713_MIN_POWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	err = si4713_send_command(sdev, SI4713_CMD_TX_TUNE_POWER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 				  args, ARRAY_SIZE(args), val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 				  ARRAY_SIZE(val), DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	v4l2_dbg(1, debug, &sdev->sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 			"%s: power=0x%02x antcap=0x%02x status=0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 			__func__, power, antcap, val[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	return si4713_wait_stc(sdev, TIMEOUT_TX_TUNE_POWER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619)  * si4713_tx_tune_measure - Enters receive mode and measures the received noise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620)  *			level in units of dBuV on the selected frequency.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621)  *			The Frequency must be between 76 and 108 MHz in 10 kHz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622)  *			units and steps of 50 kHz. The command also sets the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623)  *			antenna	tuning capacitance. A value of 0 means
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624)  *			autotuning, and a value of 1 to 191 indicates manual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625)  *			override.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626)  * @sdev: si4713_device structure for the device we are communicating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627)  * @frequency: desired frequency (76 - 108 MHz, unit 10 KHz, step 50 kHz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628)  * @antcap: value of antenna tuning capacitor (0 - 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) static int si4713_tx_tune_measure(struct si4713_device *sdev, u16 frequency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 					u8 antcap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 	u8 val[SI4713_TXMEA_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	 *	.First byte = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	 *	.Second byte = frequency's MSB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	 *	.Third byte = frequency's LSB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	 *	.Fourth byte = antcap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	const u8 args[SI4713_TXMEA_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 		0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 		msb(frequency),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 		lsb(frequency),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 		antcap,
^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) 	sdev->tune_rnl = DEFAULT_TUNE_RNL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	if (antcap > SI4713_MAX_ANTCAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 		return -EDOM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	err = si4713_send_command(sdev, SI4713_CMD_TX_TUNE_MEASURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 				  args, ARRAY_SIZE(args), val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 				  ARRAY_SIZE(val), DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 	v4l2_dbg(1, debug, &sdev->sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 			"%s: frequency=0x%02x antcap=0x%02x status=0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 			__func__, frequency, antcap, val[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	return si4713_wait_stc(sdev, TIMEOUT_TX_TUNE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) }
^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)  * si4713_tx_tune_status- Returns the status of the tx_tune_freq, tx_tune_mea or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669)  *			tx_tune_power commands. This command return the current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670)  *			frequency, output voltage in dBuV, the antenna tunning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671)  *			capacitance value and the received noise level. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672)  *			command also clears the stcint interrupt bit when the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673)  *			first bit of its arguments is high.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674)  * @sdev: si4713_device structure for the device we are communicating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675)  * @intack: 0x01 to clear the seek/tune complete interrupt status indicator.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676)  * @frequency: returned frequency
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677)  * @power: returned power
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678)  * @antcap: returned antenna capacitance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679)  * @noise: returned noise level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) static int si4713_tx_tune_status(struct si4713_device *sdev, u8 intack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 					u16 *frequency,	u8 *power,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 					u8 *antcap, u8 *noise)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	u8 val[SI4713_TXSTATUS_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	 *	.First byte = intack bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	const u8 args[SI4713_TXSTATUS_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 		intack & SI4713_INTACK_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	err = si4713_send_command(sdev, SI4713_CMD_TX_TUNE_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 				  args, ARRAY_SIZE(args), val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 				  ARRAY_SIZE(val), DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 		v4l2_dbg(1, debug, &sdev->sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 			"%s: status=0x%02x\n", __func__, val[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 		*frequency = compose_u16(val[2], val[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 		sdev->frequency = *frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 		*power = val[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 		*antcap = val[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 		*noise = val[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 		v4l2_dbg(1, debug, &sdev->sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 			 "%s: response: %d x 10 kHz (power %d, antcap %d, rnl %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 			 __func__, *frequency, *power, *antcap, *noise);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715)  * si4713_tx_rds_buff - Loads the RDS group buffer FIFO or circular buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716)  * @sdev: si4713_device structure for the device we are communicating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717)  * @mode: the buffer operation mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718)  * @rdsb: RDS Block B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719)  * @rdsc: RDS Block C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720)  * @rdsd: RDS Block D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721)  * @cbleft: returns the number of available circular buffer blocks minus the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722)  *          number of used circular buffer blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) static int si4713_tx_rds_buff(struct si4713_device *sdev, u8 mode, u16 rdsb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 				u16 rdsc, u16 rdsd, s8 *cbleft)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	u8 val[SI4713_RDSBUFF_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	const u8 args[SI4713_RDSBUFF_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 		mode & SI4713_RDSBUFF_MODE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 		msb(rdsb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 		lsb(rdsb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 		msb(rdsc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 		lsb(rdsc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 		msb(rdsd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 		lsb(rdsd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 	err = si4713_send_command(sdev, SI4713_CMD_TX_RDS_BUFF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 				  args, ARRAY_SIZE(args), val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 				  ARRAY_SIZE(val), DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 		v4l2_dbg(1, debug, &sdev->sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 			"%s: status=0x%02x\n", __func__, val[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 		*cbleft = (s8)val[2] - val[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 		v4l2_dbg(1, debug, &sdev->sd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 			 "%s: response: interrupts 0x%02x cb avail: %d cb used %d fifo avail %d fifo used %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 			 __func__, val[1], val[2], val[3], val[4], val[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757)  * si4713_tx_rds_ps - Loads the program service buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758)  * @sdev: si4713_device structure for the device we are communicating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759)  * @psid: program service id to be loaded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760)  * @pschar: assumed 4 size char array to be loaded into the program service
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) static int si4713_tx_rds_ps(struct si4713_device *sdev, u8 psid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 				unsigned char *pschar)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	u8 val[SI4713_RDSPS_NRESP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	const u8 args[SI4713_RDSPS_NARGS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		psid & SI4713_RDSPS_PSID_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 		pschar[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 		pschar[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 		pschar[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 		pschar[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	err = si4713_send_command(sdev, SI4713_CMD_TX_RDS_PS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 				  args, ARRAY_SIZE(args), val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 				  ARRAY_SIZE(val), DEFAULT_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	v4l2_dbg(1, debug, &sdev->sd, "%s: status=0x%02x\n", __func__, val[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) static int si4713_set_power_state(struct si4713_device *sdev, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	if (value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 		return si4713_powerup(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	return si4713_powerdown(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) static int si4713_set_mute(struct si4713_device *sdev, u16 mute)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	int rval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	mute = set_mute(mute);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	if (sdev->power_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 		rval = si4713_write_property(sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 				SI4713_TX_LINE_INPUT_MUTE, mute);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) static int si4713_set_rds_ps_name(struct si4713_device *sdev, char *ps_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	int rval = 0, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	u8 len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	/* We want to clear the whole thing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	if (!strlen(ps_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 		memset(ps_name, 0, MAX_RDS_PS_NAME + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	if (sdev->power_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 		/* Write the new ps name and clear the padding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 		for (i = 0; i < MAX_RDS_PS_NAME; i += (RDS_BLOCK / 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 			rval = si4713_tx_rds_ps(sdev, (i / (RDS_BLOCK / 2)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 						ps_name + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 			if (rval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 				return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 		/* Setup the size to be sent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 		if (strlen(ps_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 			len = strlen(ps_name) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 			len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 		rval = si4713_write_property(sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 				SI4713_TX_RDS_PS_MESSAGE_COUNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 				rds_ps_nblocks(len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 		if (rval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 			return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 		rval = si4713_write_property(sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 				SI4713_TX_RDS_PS_REPEAT_COUNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 				DEFAULT_RDS_PS_REPEAT_COUNT * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 		if (rval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 			return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) static int si4713_set_rds_radio_text(struct si4713_device *sdev, const char *rt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	static const char cr[RDS_RADIOTEXT_BLK_SIZE] = { RDS_CARRIAGE_RETURN, 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	int rval = 0, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	u16 t_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	u8 b_index = 0, cr_inserted = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	s8 left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	if (!sdev->power_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	rval = si4713_tx_rds_buff(sdev, RDS_BLOCK_CLEAR, 0, 0, 0, &left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	if (rval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	if (!strlen(rt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 		/* RDS spec says that if the last block isn't used,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 		 * then apply a carriage return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 		if (t_index < (RDS_RADIOTEXT_INDEX_MAX * RDS_RADIOTEXT_BLK_SIZE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 			for (i = 0; i < RDS_RADIOTEXT_BLK_SIZE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 				if (!rt[t_index + i] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 				    rt[t_index + i] == RDS_CARRIAGE_RETURN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 					rt = cr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 					cr_inserted = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 				}
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 		rval = si4713_tx_rds_buff(sdev, RDS_BLOCK_LOAD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 				compose_u16(RDS_RADIOTEXT_2A, b_index++),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 				compose_u16(rt[t_index], rt[t_index + 1]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 				compose_u16(rt[t_index + 2], rt[t_index + 3]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 				&left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 		if (rval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 			return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		t_index += RDS_RADIOTEXT_BLK_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 		if (cr_inserted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	} while (left > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899)  * si4713_update_tune_status - update properties from tx_tune_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900)  * command. Must be called with sdev->mutex held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901)  * @sdev: si4713_device structure for the device we are communicating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) static int si4713_update_tune_status(struct si4713_device *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	u16 f = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	u8 p = 0, a = 0, n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	rval = si4713_tx_tune_status(sdev, 0x00, &f, &p, &a, &n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	if (rval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) /*	TODO: check that power_level and antenna_capacitor really are not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	changed by the hardware. If they are, then these controls should become
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	volatiles.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	sdev->power_level = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	sdev->antenna_capacitor = a;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	sdev->tune_rnl = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) static int si4713_choose_econtrol_action(struct si4713_device *sdev, u32 id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 		s32 *bit, s32 *mask, u16 *property, int *mul,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 		unsigned long **table, int *size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	s32 rval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	switch (id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	/* FM_TX class controls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	case V4L2_CID_RDS_TX_PI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 		*property = SI4713_TX_RDS_PI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 		*mul = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 		*property = SI4713_TX_ACOMP_THRESHOLD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 		*mul = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	case V4L2_CID_AUDIO_COMPRESSION_GAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 		*property = SI4713_TX_ACOMP_GAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 		*mul = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	case V4L2_CID_PILOT_TONE_FREQUENCY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 		*property = SI4713_TX_PILOT_FREQUENCY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 		*mul = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 		*property = SI4713_TX_ACOMP_ATTACK_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 		*mul = ATTACK_TIME_UNIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	case V4L2_CID_PILOT_TONE_DEVIATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 		*property = SI4713_TX_PILOT_DEVIATION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 		*mul = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	case V4L2_CID_AUDIO_LIMITER_DEVIATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 		*property = SI4713_TX_AUDIO_DEVIATION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 		*mul = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	case V4L2_CID_RDS_TX_DEVIATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 		*property = SI4713_TX_RDS_DEVIATION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 		*mul = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	case V4L2_CID_RDS_TX_PTY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 		*property = SI4713_TX_RDS_PS_MISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		*bit = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 		*mask = 0x1F << 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 	case V4L2_CID_RDS_TX_DYNAMIC_PTY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 		*property = SI4713_TX_RDS_PS_MISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 		*bit = 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 		*mask = 1 << 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	case V4L2_CID_RDS_TX_COMPRESSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 		*property = SI4713_TX_RDS_PS_MISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 		*bit = 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 		*mask = 1 << 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	case V4L2_CID_RDS_TX_ARTIFICIAL_HEAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 		*property = SI4713_TX_RDS_PS_MISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 		*bit = 13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 		*mask = 1 << 13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	case V4L2_CID_RDS_TX_MONO_STEREO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 		*property = SI4713_TX_RDS_PS_MISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		*bit = 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 		*mask = 1 << 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 		*property = SI4713_TX_RDS_PS_MISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 		*bit = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 		*mask = 1 << 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 		*property = SI4713_TX_RDS_PS_MISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 		*bit = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 		*mask = 1 << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	case V4L2_CID_RDS_TX_MUSIC_SPEECH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 		*property = SI4713_TX_RDS_PS_MISC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 		*bit = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 		*mask = 1 << 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	case V4L2_CID_AUDIO_LIMITER_ENABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 		*property = SI4713_TX_ACOMP_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 		*bit = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 		*mask = 1 << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	case V4L2_CID_AUDIO_COMPRESSION_ENABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 		*property = SI4713_TX_ACOMP_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 		*bit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 		*mask = 1 << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	case V4L2_CID_PILOT_TONE_ENABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 		*property = SI4713_TX_COMPONENT_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 		*bit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 		*mask = 1 << 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 		*property = SI4713_TX_LIMITER_RELEASE_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 		*table = limiter_times;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 		*size = ARRAY_SIZE(limiter_times);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 		*property = SI4713_TX_ACOMP_RELEASE_TIME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 		*table = acomp_rtimes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 		*size = ARRAY_SIZE(acomp_rtimes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	case V4L2_CID_TUNE_PREEMPHASIS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 		*property = SI4713_TX_PREEMPHASIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 		*table = preemphasis_values;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 		*size = ARRAY_SIZE(preemphasis_values);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 		rval = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) static int si4713_s_frequency(struct v4l2_subdev *sd, const struct v4l2_frequency *f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) static int si4713_s_modulator(struct v4l2_subdev *sd, const struct v4l2_modulator *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)  * si4713_setup - Sets the device up with current configuration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)  * @sdev: si4713_device structure for the device we are communicating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) static int si4713_setup(struct si4713_device *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	struct v4l2_frequency f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	struct v4l2_modulator vm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	/* Device procedure needs to set frequency first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	f.tuner = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	f.frequency = sdev->frequency ? sdev->frequency : DEFAULT_FREQUENCY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	f.frequency = si4713_to_v4l2(f.frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	rval = si4713_s_frequency(&sdev->sd, &f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	vm.index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	if (sdev->stereo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 		vm.txsubchans = V4L2_TUNER_SUB_STEREO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 		vm.txsubchans = V4L2_TUNER_SUB_MONO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	if (sdev->rds_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 		vm.txsubchans |= V4L2_TUNER_SUB_RDS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	si4713_s_modulator(&sdev->sd, &vm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)  * si4713_initialize - Sets the device up with default configuration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)  * @sdev: si4713_device structure for the device we are communicating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) static int si4713_initialize(struct si4713_device *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	rval = si4713_set_power_state(sdev, POWER_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	if (rval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	rval = si4713_checkrev(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	if (rval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	rval = si4713_set_power_state(sdev, POWER_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	if (rval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 		return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	sdev->frequency = DEFAULT_FREQUENCY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	sdev->stereo = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	sdev->tune_rnl = DEFAULT_TUNE_RNL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) /* si4713_s_ctrl - set the value of a control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) static int si4713_s_ctrl(struct v4l2_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	struct si4713_device *sdev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 		container_of(ctrl->handler, struct si4713_device, ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	u32 val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	s32 bit = 0, mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	u16 property = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	int mul = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	unsigned long *table = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	int size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	bool force = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	int c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	if (ctrl->id != V4L2_CID_AUDIO_MUTE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	if (ctrl->is_new) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 		if (ctrl->val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 			ret = si4713_set_mute(sdev, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 			if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 				ret = si4713_set_power_state(sdev, POWER_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 		ret = si4713_set_power_state(sdev, POWER_UP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 		if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 			ret = si4713_set_mute(sdev, ctrl->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 		if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 			ret = si4713_setup(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 		force = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	if (!sdev->power_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	for (c = 1; !ret && c < ctrl->ncontrols; c++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 		ctrl = ctrl->cluster[c];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 		if (!force && !ctrl->is_new)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 		switch (ctrl->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 		case V4L2_CID_RDS_TX_PS_NAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 			ret = si4713_set_rds_ps_name(sdev, ctrl->p_new.p_char);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 		case V4L2_CID_RDS_TX_RADIO_TEXT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 			ret = si4713_set_rds_radio_text(sdev, ctrl->p_new.p_char);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 		case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 			/* don't handle this control if we force setting all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 			 * controls since in that case it will be handled by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 			 * V4L2_CID_TUNE_POWER_LEVEL. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 			if (force)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 		case V4L2_CID_TUNE_POWER_LEVEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 			ret = si4713_tx_tune_power(sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 				sdev->tune_pwr_level->val, sdev->tune_ant_cap->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 			if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 				/* Make sure we don't set this twice */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 				sdev->tune_ant_cap->is_new = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 				sdev->tune_pwr_level->is_new = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 		case V4L2_CID_RDS_TX_ALT_FREQS_ENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 		case V4L2_CID_RDS_TX_ALT_FREQS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 			if (sdev->rds_alt_freqs_enable->val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 				val = sdev->rds_alt_freqs->p_new.p_u32[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 				val = val / 100 - 876 + 0xe101;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 				val = 0xe0e0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 			ret = si4713_write_property(sdev, SI4713_TX_RDS_PS_AF, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 			ret = si4713_choose_econtrol_action(sdev, ctrl->id, &bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 					&mask, &property, &mul, &table, &size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 			val = ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 			if (mul) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 				val = val / mul;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 			} else if (table) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 				ret = usecs_to_dev(val, table, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 				if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 				val = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 				ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 			if (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 				ret = si4713_read_property(sdev, property, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 				if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 				val = set_bits(val, ctrl->val, bit, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 			ret = si4713_write_property(sdev, property, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 			if (mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 				val = ctrl->val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) /* si4713_ioctl - deal with private ioctls (only rnl for now) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) static long si4713_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	struct si4713_device *sdev = to_si4713_device(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	struct si4713_rnl *rnl = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 	u16 frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 	int rval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 	if (!arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	case SI4713_IOC_MEASURE_RNL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 		frequency = v4l2_to_si4713(rnl->frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 		if (sdev->power_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 			/* Set desired measurement frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 			rval = si4713_tx_tune_measure(sdev, frequency, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 			if (rval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 				return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 			/* get results from tune status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 			rval = si4713_update_tune_status(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 			if (rval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 				return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 		rnl->rnl = sdev->tune_rnl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 		/* nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 		rval = -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) /* si4713_g_modulator - get modulator attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) static int si4713_g_modulator(struct v4l2_subdev *sd, struct v4l2_modulator *vm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 	struct si4713_device *sdev = to_si4713_device(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 	int rval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 	if (!sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 	if (vm->index > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	strscpy(vm->name, "FM Modulator", sizeof(vm->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 	vm->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LOW |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 		V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_CONTROLS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 	/* Report current frequency range limits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 	vm->rangelow = si4713_to_v4l2(FREQ_RANGE_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 	vm->rangehigh = si4713_to_v4l2(FREQ_RANGE_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	if (sdev->power_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 		u32 comp_en = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 		rval = si4713_read_property(sdev, SI4713_TX_COMPONENT_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 						&comp_en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 		if (rval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 			return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 		sdev->stereo = get_status_bit(comp_en, 1, 1 << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	/* Report current audio mode: mono or stereo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 	if (sdev->stereo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 		vm->txsubchans = V4L2_TUNER_SUB_STEREO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 		vm->txsubchans = V4L2_TUNER_SUB_MONO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 	/* Report rds feature status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	if (sdev->rds_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 		vm->txsubchans |= V4L2_TUNER_SUB_RDS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 		vm->txsubchans &= ~V4L2_TUNER_SUB_RDS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) /* si4713_s_modulator - set modulator attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) static int si4713_s_modulator(struct v4l2_subdev *sd, const struct v4l2_modulator *vm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	struct si4713_device *sdev = to_si4713_device(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 	int rval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 	u16 stereo, rds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 	u32 p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 	if (!sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 	if (vm->index > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 	/* Set audio mode: mono or stereo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 	if (vm->txsubchans & V4L2_TUNER_SUB_STEREO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 		stereo = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	else if (vm->txsubchans & V4L2_TUNER_SUB_MONO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 		stereo = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	rds = !!(vm->txsubchans & V4L2_TUNER_SUB_RDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	if (sdev->power_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 		rval = si4713_read_property(sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 						SI4713_TX_COMPONENT_ENABLE, &p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 		if (rval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 			return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 		p = set_bits(p, stereo, 1, 1 << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 		p = set_bits(p, rds, 2, 1 << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 		rval = si4713_write_property(sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 						SI4713_TX_COMPONENT_ENABLE, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 		if (rval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 			return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	sdev->stereo = stereo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	sdev->rds_enabled = rds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) /* si4713_g_frequency - get tuner or modulator radio frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) static int si4713_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	struct si4713_device *sdev = to_si4713_device(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	int rval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	if (f->tuner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	if (sdev->power_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 		u16 freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 		u8 p, a, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 		rval = si4713_tx_tune_status(sdev, 0x00, &freq, &p, &a, &n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 		if (rval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 			return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 		sdev->frequency = 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) 	f->frequency = si4713_to_v4l2(sdev->frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 	return rval;
^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) /* si4713_s_frequency - set tuner or modulator radio frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) static int si4713_s_frequency(struct v4l2_subdev *sd, const struct v4l2_frequency *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 	struct si4713_device *sdev = to_si4713_device(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 	int rval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 	u16 frequency = v4l2_to_si4713(f->frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 	if (f->tuner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 	/* Check frequency range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 	frequency = clamp_t(u16, frequency, FREQ_RANGE_LOW, FREQ_RANGE_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 	if (sdev->power_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 		rval = si4713_tx_tune_freq(sdev, frequency);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 		if (rval < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 			return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 		frequency = rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 		rval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	sdev->frequency = frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) static const struct v4l2_ctrl_ops si4713_ctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 	.s_ctrl = si4713_s_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) static const struct v4l2_subdev_core_ops si4713_subdev_core_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 	.ioctl		= si4713_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) static const struct v4l2_subdev_tuner_ops si4713_subdev_tuner_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 	.g_frequency	= si4713_g_frequency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 	.s_frequency	= si4713_s_frequency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 	.g_modulator	= si4713_g_modulator,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 	.s_modulator	= si4713_s_modulator,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) static const struct v4l2_subdev_ops si4713_subdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 	.core		= &si4713_subdev_core_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 	.tuner		= &si4713_subdev_tuner_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) static const struct v4l2_ctrl_config si4713_alt_freqs_ctrl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 	.id = V4L2_CID_RDS_TX_ALT_FREQS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 	.type = V4L2_CTRL_TYPE_U32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	.min = 87600,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	.max = 107900,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	.step = 100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	.def = 87600,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 	.dims = { 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 	.elem_size = sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427)  * I2C driver interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) /* si4713_probe - probe for the device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) static int si4713_probe(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 	struct si4713_device *sdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 	struct v4l2_ctrl_handler *hdl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 	struct si4713_platform_data *pdata = client->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 	struct device_node *np = client->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 	struct radio_si4713_platform_data si4713_pdev_pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 	struct platform_device *si4713_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 	int rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 	sdev = devm_kzalloc(&client->dev, sizeof(*sdev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 	if (!sdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 		dev_err(&client->dev, "Failed to alloc video device.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 		rval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 	sdev->gpio_reset = devm_gpiod_get_optional(&client->dev, "reset",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 						   GPIOD_OUT_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 	if (IS_ERR(sdev->gpio_reset)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 		rval = PTR_ERR(sdev->gpio_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 		dev_err(&client->dev, "Failed to request gpio: %d\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 	sdev->vdd = devm_regulator_get_optional(&client->dev, "vdd");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 	if (IS_ERR(sdev->vdd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 		rval = PTR_ERR(sdev->vdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 		if (rval == -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 			goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 		dev_dbg(&client->dev, "no vdd regulator found: %d\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 		sdev->vdd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 	sdev->vio = devm_regulator_get_optional(&client->dev, "vio");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 	if (IS_ERR(sdev->vio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 		rval = PTR_ERR(sdev->vio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 		if (rval == -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 			goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 		dev_dbg(&client->dev, "no vio regulator found: %d\n", rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 		sdev->vio = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 	v4l2_i2c_subdev_init(&sdev->sd, client, &si4713_subdev_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 	init_completion(&sdev->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 	hdl = &sdev->ctrl_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 	v4l2_ctrl_handler_init(hdl, 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 	sdev->mute = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 			V4L2_CID_AUDIO_MUTE, 0, 1, 1, DEFAULT_MUTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 	sdev->rds_pi = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 			V4L2_CID_RDS_TX_PI, 0, 0xffff, 1, DEFAULT_RDS_PI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 	sdev->rds_pty = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 			V4L2_CID_RDS_TX_PTY, 0, 31, 1, DEFAULT_RDS_PTY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 	sdev->rds_compressed = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 			V4L2_CID_RDS_TX_COMPRESSED, 0, 1, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 	sdev->rds_art_head = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 			V4L2_CID_RDS_TX_ARTIFICIAL_HEAD, 0, 1, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 	sdev->rds_stereo = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 			V4L2_CID_RDS_TX_MONO_STEREO, 0, 1, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 	sdev->rds_tp = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 			V4L2_CID_RDS_TX_TRAFFIC_PROGRAM, 0, 1, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 	sdev->rds_ta = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 			V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT, 0, 1, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 	sdev->rds_ms = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 			V4L2_CID_RDS_TX_MUSIC_SPEECH, 0, 1, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 	sdev->rds_dyn_pty = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 			V4L2_CID_RDS_TX_DYNAMIC_PTY, 0, 1, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 	sdev->rds_alt_freqs_enable = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 			V4L2_CID_RDS_TX_ALT_FREQS_ENABLE, 0, 1, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 	sdev->rds_alt_freqs = v4l2_ctrl_new_custom(hdl, &si4713_alt_freqs_ctrl, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 	sdev->rds_deviation = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 			V4L2_CID_RDS_TX_DEVIATION, 0, MAX_RDS_DEVIATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 			10, DEFAULT_RDS_DEVIATION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 	 * Report step as 8. From RDS spec, psname
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 	 * should be 8. But there are receivers which scroll strings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 	 * sized as 8xN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 	sdev->rds_ps_name = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 			V4L2_CID_RDS_TX_PS_NAME, 0, MAX_RDS_PS_NAME, 8, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 	 * Report step as 32 (2A block). From RDS spec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 	 * radio text should be 32 for 2A block. But there are receivers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 	 * which scroll strings sized as 32xN. Setting default to 32.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 	sdev->rds_radio_text = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 			V4L2_CID_RDS_TX_RADIO_TEXT, 0, MAX_RDS_RADIO_TEXT, 32, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 	sdev->limiter_enabled = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 			V4L2_CID_AUDIO_LIMITER_ENABLED, 0, 1, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 	sdev->limiter_release_time = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 			V4L2_CID_AUDIO_LIMITER_RELEASE_TIME, 250,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 			MAX_LIMITER_RELEASE_TIME, 10, DEFAULT_LIMITER_RTIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 	sdev->limiter_deviation = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 			V4L2_CID_AUDIO_LIMITER_DEVIATION, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 			MAX_LIMITER_DEVIATION, 10, DEFAULT_LIMITER_DEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 	sdev->compression_enabled = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 			V4L2_CID_AUDIO_COMPRESSION_ENABLED, 0, 1, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 	sdev->compression_gain = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 			V4L2_CID_AUDIO_COMPRESSION_GAIN, 0, MAX_ACOMP_GAIN, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 			DEFAULT_ACOMP_GAIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 	sdev->compression_threshold = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 			V4L2_CID_AUDIO_COMPRESSION_THRESHOLD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 			MIN_ACOMP_THRESHOLD, MAX_ACOMP_THRESHOLD, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 			DEFAULT_ACOMP_THRESHOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 	sdev->compression_attack_time = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 			V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 			MAX_ACOMP_ATTACK_TIME, 500, DEFAULT_ACOMP_ATIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 	sdev->compression_release_time = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 			V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME, 100000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 			MAX_ACOMP_RELEASE_TIME, 100000, DEFAULT_ACOMP_RTIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 	sdev->pilot_tone_enabled = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 			V4L2_CID_PILOT_TONE_ENABLED, 0, 1, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 	sdev->pilot_tone_deviation = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 			V4L2_CID_PILOT_TONE_DEVIATION, 0, MAX_PILOT_DEVIATION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 			10, DEFAULT_PILOT_DEVIATION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 	sdev->pilot_tone_freq = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 			V4L2_CID_PILOT_TONE_FREQUENCY, 0, MAX_PILOT_FREQUENCY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 			1, DEFAULT_PILOT_FREQUENCY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 	sdev->tune_preemphasis = v4l2_ctrl_new_std_menu(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 			V4L2_CID_TUNE_PREEMPHASIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 			V4L2_PREEMPHASIS_75_uS, 0, V4L2_PREEMPHASIS_50_uS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 	sdev->tune_pwr_level = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 			V4L2_CID_TUNE_POWER_LEVEL, 0, SI4713_MAX_POWER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 			1, DEFAULT_POWER_LEVEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 	sdev->tune_ant_cap = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 			V4L2_CID_TUNE_ANTENNA_CAPACITOR, 0, SI4713_MAX_ANTCAP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 			1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 	if (hdl->error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 		rval = hdl->error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 		goto free_ctrls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 	v4l2_ctrl_cluster(29, &sdev->mute);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 	sdev->sd.ctrl_handler = hdl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 	if (client->irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 		rval = devm_request_irq(&client->dev, client->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 			si4713_handler, IRQF_TRIGGER_FALLING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 			client->name, sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 		if (rval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 			v4l2_err(&sdev->sd, "Could not request IRQ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 			goto free_ctrls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 		v4l2_dbg(1, debug, &sdev->sd, "IRQ requested.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 		v4l2_warn(&sdev->sd, "IRQ not configured. Using timeouts.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 	rval = si4713_initialize(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 	if (rval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 		v4l2_err(&sdev->sd, "Failed to probe device information.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 		goto free_ctrls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 	if (!np && (!pdata || !pdata->is_platform_device))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 	si4713_pdev = platform_device_alloc("radio-si4713", -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 	if (!si4713_pdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 		rval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 		goto put_main_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 	si4713_pdev_pdata.subdev = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 	rval = platform_device_add_data(si4713_pdev, &si4713_pdev_pdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 					sizeof(si4713_pdev_pdata));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 	if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 		goto put_main_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 	rval = platform_device_add(si4713_pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 	if (rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 		goto put_main_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 	sdev->pd = si4713_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) put_main_pdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 	platform_device_put(si4713_pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 	v4l2_device_unregister_subdev(&sdev->sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) free_ctrls:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 	v4l2_ctrl_handler_free(hdl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) /* si4713_remove - remove the device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) static int si4713_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 	struct si4713_device *sdev = to_si4713_device(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 	platform_device_unregister(sdev->pd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 	if (sdev->power_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 		si4713_set_power_state(sdev, POWER_DOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 	v4l2_device_unregister_subdev(sd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 	v4l2_ctrl_handler_free(sd->ctrl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) /* si4713_i2c_driver - i2c driver interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) static const struct i2c_device_id si4713_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 	{ "si4713" , 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 	{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) MODULE_DEVICE_TABLE(i2c, si4713_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) #if IS_ENABLED(CONFIG_OF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) static const struct of_device_id si4713_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 	{ .compatible = "silabs,si4713" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 	{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) MODULE_DEVICE_TABLE(of, si4713_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) static struct i2c_driver si4713_i2c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 	.driver		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 		.name	= "si4713",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 		.of_match_table = of_match_ptr(si4713_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 	.probe_new	= si4713_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 	.remove         = si4713_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 	.id_table       = si4713_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) module_i2c_driver(si4713_i2c_driver);