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)  * Copyright (C) 2018 Renesas Electronics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Copyright (C) 2016 Atmel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *		      Bo Shen <voice.shen@atmel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * Authors:	      Bo Shen <voice.shen@atmel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  *		      Boris Brezillon <boris.brezillon@free-electrons.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  *		      Wu, Songjun <Songjun.Wu@atmel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/i2c-mux.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/i2c.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 <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <drm/drm_atomic_helper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <drm/drm_bridge.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <drm/drm_drv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <drm/drm_edid.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <drm/drm_modes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <drm/drm_print.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <drm/drm_probe_helper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <sound/hdmi-codec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <video/videomode.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #define SII902X_TPI_VIDEO_DATA			0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #define SII902X_TPI_PIXEL_REPETITION		0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #define SII902X_TPI_AVI_PIXEL_REP_BUS_24BIT     BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #define SII902X_TPI_AVI_PIXEL_REP_RISING_EDGE   BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #define SII902X_TPI_AVI_PIXEL_REP_4X		3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #define SII902X_TPI_AVI_PIXEL_REP_2X		1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #define SII902X_TPI_AVI_PIXEL_REP_NONE		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #define SII902X_TPI_CLK_RATIO_HALF		(0 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #define SII902X_TPI_CLK_RATIO_1X		(1 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #define SII902X_TPI_CLK_RATIO_2X		(2 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #define SII902X_TPI_CLK_RATIO_4X		(3 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #define SII902X_TPI_AVI_IN_FORMAT		0x9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #define SII902X_TPI_AVI_INPUT_BITMODE_12BIT	BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #define SII902X_TPI_AVI_INPUT_DITHER		BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #define SII902X_TPI_AVI_INPUT_RANGE_LIMITED	(2 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #define SII902X_TPI_AVI_INPUT_RANGE_FULL	(1 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #define SII902X_TPI_AVI_INPUT_RANGE_AUTO	(0 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #define SII902X_TPI_AVI_INPUT_COLORSPACE_BLACK	(3 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #define SII902X_TPI_AVI_INPUT_COLORSPACE_YUV422	(2 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #define SII902X_TPI_AVI_INPUT_COLORSPACE_YUV444	(1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #define SII902X_TPI_AVI_INPUT_COLORSPACE_RGB	(0 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #define SII902X_TPI_AVI_INFOFRAME		0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #define SII902X_SYS_CTRL_DATA			0x1a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) #define SII902X_SYS_CTRL_PWR_DWN		BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) #define SII902X_SYS_CTRL_AV_MUTE		BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) #define SII902X_SYS_CTRL_DDC_BUS_REQ		BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) #define SII902X_SYS_CTRL_DDC_BUS_GRTD		BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) #define SII902X_SYS_CTRL_OUTPUT_MODE		BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) #define SII902X_SYS_CTRL_OUTPUT_HDMI		1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) #define SII902X_SYS_CTRL_OUTPUT_DVI		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) #define SII902X_REG_CHIPID(n)			(0x1b + (n))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) #define SII902X_PWR_STATE_CTRL			0x1e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) #define SII902X_AVI_POWER_STATE_MSK		GENMASK(1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) #define SII902X_AVI_POWER_STATE_D(l)		((l) & SII902X_AVI_POWER_STATE_MSK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) /* Audio  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) #define SII902X_TPI_I2S_ENABLE_MAPPING_REG	0x1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) #define SII902X_TPI_I2S_CONFIG_FIFO0			(0 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) #define SII902X_TPI_I2S_CONFIG_FIFO1			(1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) #define SII902X_TPI_I2S_CONFIG_FIFO2			(2 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) #define SII902X_TPI_I2S_CONFIG_FIFO3			(3 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) #define SII902X_TPI_I2S_LEFT_RIGHT_SWAP			(1 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) #define SII902X_TPI_I2S_AUTO_DOWNSAMPLE			(1 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) #define SII902X_TPI_I2S_SELECT_SD0			(0 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) #define SII902X_TPI_I2S_SELECT_SD1			(1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) #define SII902X_TPI_I2S_SELECT_SD2			(2 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) #define SII902X_TPI_I2S_SELECT_SD3			(3 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) #define SII902X_TPI_I2S_FIFO_ENABLE			(1 << 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) #define SII902X_TPI_I2S_INPUT_CONFIG_REG	0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) #define SII902X_TPI_I2S_FIRST_BIT_SHIFT_YES		(0 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) #define SII902X_TPI_I2S_FIRST_BIT_SHIFT_NO		(1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) #define SII902X_TPI_I2S_SD_DIRECTION_MSB_FIRST		(0 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) #define SII902X_TPI_I2S_SD_DIRECTION_LSB_FIRST		(1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) #define SII902X_TPI_I2S_SD_JUSTIFY_LEFT			(0 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) #define SII902X_TPI_I2S_SD_JUSTIFY_RIGHT		(1 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) #define SII902X_TPI_I2S_WS_POLARITY_LOW			(0 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) #define SII902X_TPI_I2S_WS_POLARITY_HIGH		(1 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) #define SII902X_TPI_I2S_MCLK_MULTIPLIER_128		(0 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) #define SII902X_TPI_I2S_MCLK_MULTIPLIER_256		(1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) #define SII902X_TPI_I2S_MCLK_MULTIPLIER_384		(2 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) #define SII902X_TPI_I2S_MCLK_MULTIPLIER_512		(3 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) #define SII902X_TPI_I2S_MCLK_MULTIPLIER_768		(4 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) #define SII902X_TPI_I2S_MCLK_MULTIPLIER_1024		(5 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) #define SII902X_TPI_I2S_MCLK_MULTIPLIER_1152		(6 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) #define SII902X_TPI_I2S_MCLK_MULTIPLIER_192		(7 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) #define SII902X_TPI_I2S_SCK_EDGE_FALLING		(0 << 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) #define SII902X_TPI_I2S_SCK_EDGE_RISING			(1 << 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) #define SII902X_TPI_I2S_STRM_HDR_BASE	0x21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) #define SII902X_TPI_I2S_STRM_HDR_SIZE	5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) #define SII902X_TPI_AUDIO_CONFIG_BYTE2_REG	0x26
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) #define SII902X_TPI_AUDIO_CODING_STREAM_HEADER		(0 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) #define SII902X_TPI_AUDIO_CODING_PCM			(1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) #define SII902X_TPI_AUDIO_CODING_AC3			(2 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) #define SII902X_TPI_AUDIO_CODING_MPEG1			(3 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) #define SII902X_TPI_AUDIO_CODING_MP3			(4 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) #define SII902X_TPI_AUDIO_CODING_MPEG2			(5 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) #define SII902X_TPI_AUDIO_CODING_AAC			(6 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) #define SII902X_TPI_AUDIO_CODING_DTS			(7 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) #define SII902X_TPI_AUDIO_CODING_ATRAC			(8 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) #define SII902X_TPI_AUDIO_MUTE_DISABLE			(0 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) #define SII902X_TPI_AUDIO_MUTE_ENABLE			(1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) #define SII902X_TPI_AUDIO_LAYOUT_2_CHANNELS		(0 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) #define SII902X_TPI_AUDIO_LAYOUT_8_CHANNELS		(1 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) #define SII902X_TPI_AUDIO_INTERFACE_DISABLE		(0 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) #define SII902X_TPI_AUDIO_INTERFACE_SPDIF		(1 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) #define SII902X_TPI_AUDIO_INTERFACE_I2S			(2 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) #define SII902X_TPI_AUDIO_CONFIG_BYTE3_REG	0x27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) #define SII902X_TPI_AUDIO_FREQ_STREAM			(0 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) #define SII902X_TPI_AUDIO_FREQ_32KHZ			(1 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) #define SII902X_TPI_AUDIO_FREQ_44KHZ			(2 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) #define SII902X_TPI_AUDIO_FREQ_48KHZ			(3 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) #define SII902X_TPI_AUDIO_FREQ_88KHZ			(4 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) #define SII902X_TPI_AUDIO_FREQ_96KHZ			(5 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) #define SII902X_TPI_AUDIO_FREQ_176KHZ			(6 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) #define SII902X_TPI_AUDIO_FREQ_192KHZ			(7 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) #define SII902X_TPI_AUDIO_SAMPLE_SIZE_STREAM		(0 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) #define SII902X_TPI_AUDIO_SAMPLE_SIZE_16		(1 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) #define SII902X_TPI_AUDIO_SAMPLE_SIZE_20		(2 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) #define SII902X_TPI_AUDIO_SAMPLE_SIZE_24		(3 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) #define SII902X_TPI_AUDIO_CONFIG_BYTE4_REG	0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) #define SII902X_INT_ENABLE			0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) #define SII902X_INT_STATUS			0x3d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) #define SII902X_HOTPLUG_EVENT			BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) #define SII902X_PLUGGED_STATUS			BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) #define SII902X_TPI_SYNC_GEN_CTRL		0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) #define SII902X_TPI_SYNC_POLAR_DETECT		0x61
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) #define SII902X_TPI_HBIT_TO_HSYNC		0x62
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) #define SII902X_EMBEDDED_SYNC_EXTRACTION_REG	0x63
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) #define SII902X_EMBEDDED_SYNC_EXTRACTION	BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) #define SII902X_REG_TPI_RQB			0xc7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) /* Indirect internal register access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) #define SII902X_IND_SET_PAGE			0xbc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) #define SII902X_IND_OFFSET			0xbd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) #define SII902X_IND_VALUE			0xbe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) #define SII902X_TPI_MISC_INFOFRAME_BASE		0xbf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) #define SII902X_TPI_MISC_INFOFRAME_END		0xde
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) #define SII902X_TPI_MISC_INFOFRAME_SIZE	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	(SII902X_TPI_MISC_INFOFRAME_END - SII902X_TPI_MISC_INFOFRAME_BASE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) #define SII902X_I2C_BUS_ACQUISITION_TIMEOUT_MS	500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) #define SII902X_AUDIO_PORT_INDEX		3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) struct sii902x {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	struct i2c_client *i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	struct drm_bridge bridge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	struct drm_connector connector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	struct gpio_desc *reset_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	struct gpio_desc *enable_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	struct i2c_mux_core *i2cmux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	struct regulator_bulk_data supplies[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	 * Mutex protects audio and video functions from interfering
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	 * each other, by keeping their i2c command sequences atomic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	struct mutex mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	struct sii902x_audio {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 		struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 		struct clk *mclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 		u32 i2s_fifo_sequence[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	} audio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	struct drm_display_mode mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	int bus_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) enum sii902x_bus_format {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	FORMAT_RGB_INPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	FORMAT_YCBCR422_INPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	FORMAT_YCBCR444_INPUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) static int sii902x_read_unlocked(struct i2c_client *i2c, u8 reg, u8 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	union i2c_smbus_data data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	ret = __i2c_smbus_xfer(i2c->adapter, i2c->addr, i2c->flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 			       I2C_SMBUS_READ, reg, I2C_SMBUS_BYTE_DATA, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	*val = data.byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	return 0;
^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) static int sii902x_write_unlocked(struct i2c_client *i2c, u8 reg, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	union i2c_smbus_data data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	data.byte = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	return __i2c_smbus_xfer(i2c->adapter, i2c->addr, i2c->flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 				I2C_SMBUS_WRITE, reg, I2C_SMBUS_BYTE_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 				&data);
^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) static int sii902x_update_bits_unlocked(struct i2c_client *i2c, u8 reg, u8 mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 					u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	ret = sii902x_read_unlocked(i2c, reg, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	status &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	status |= val & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	return sii902x_write_unlocked(i2c, reg, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) static inline struct sii902x *bridge_to_sii902x(struct drm_bridge *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	return container_of(bridge, struct sii902x, bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) static inline struct sii902x *connector_to_sii902x(struct drm_connector *con)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	return container_of(con, struct sii902x, connector);
^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) static void sii902x_reset(struct sii902x *sii902x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	if (!sii902x->reset_gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	gpiod_set_value(sii902x->reset_gpio, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	/* The datasheet says treset-min = 100us. Make it 150us to be sure. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	usleep_range(150, 200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	gpiod_set_value(sii902x->reset_gpio, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) static enum drm_connector_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) sii902x_connector_detect(struct drm_connector *connector, bool force)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	struct sii902x *sii902x = connector_to_sii902x(connector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	unsigned int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	mutex_lock(&sii902x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	regmap_read(sii902x->regmap, SII902X_INT_STATUS, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	mutex_unlock(&sii902x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	return (status & SII902X_PLUGGED_STATUS) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	       connector_status_connected : connector_status_disconnected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) static const struct drm_connector_funcs sii902x_connector_funcs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	.detect = sii902x_connector_detect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	.fill_modes = drm_helper_probe_single_connector_modes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	.destroy = drm_connector_cleanup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	.reset = drm_atomic_helper_connector_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
^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) static const struct drm_display_mode sii902x_default_modes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	/* 4 - 1280x720@60Hz 16:9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 		   1430, 1650, 0, 720, 725, 730, 750, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	/* 16 - 1920x1080@60Hz 16:9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 		   2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	/* 5 - 1920x1080i@60Hz 16:9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	{ DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 		   2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 		   DRM_MODE_FLAG_INTERLACE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	/* 31 - 1920x1080@50Hz 16:9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 		   2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	/* 19 - 1280x720@50Hz 16:9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1720,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 		   1760, 1980, 0, 720, 725, 730, 750, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	/* 0x10 - 1024x768@60Hz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 		   1184, 1344, 0,  768, 771, 777, 806, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	/* 17 - 720x576@50Hz 4:3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	{ DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 		   796, 864, 0, 576, 581, 586, 625, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	/* 2 - 720x480@60Hz 4:3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	{ DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 		   798, 858, 0, 480, 489, 495, 525, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	  .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) static int sii902x_get_modes(struct drm_connector *connector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	struct sii902x *sii902x = connector_to_sii902x(connector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	u8 output_mode = SII902X_SYS_CTRL_OUTPUT_DVI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	struct edid *edid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	int num = 0, ret = 0, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	struct drm_display_mode *mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	mutex_lock(&sii902x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	edid = drm_get_edid(connector, sii902x->i2cmux->adapter[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	drm_connector_update_edid_property(connector, edid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 	if (edid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 		if (drm_detect_hdmi_monitor(edid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 			output_mode = SII902X_SYS_CTRL_OUTPUT_HDMI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 		num = drm_add_edid_modes(connector, edid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 		kfree(edid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 		for (i = 0; i < ARRAY_SIZE(sii902x_default_modes); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 			const struct drm_display_mode *ptr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 				&sii902x_default_modes[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 			mode = drm_mode_duplicate(connector->dev, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 			if (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 				if (!i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 					mode->type = DRM_MODE_TYPE_PREFERRED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 				drm_mode_probed_add(connector, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 				ret++;
^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) 		output_mode = SII902X_SYS_CTRL_OUTPUT_HDMI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	ret = drm_display_info_set_bus_formats(&connector->display_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 					       &sii902x->bus_format, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 		goto error_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	ret = regmap_update_bits(sii902x->regmap, SII902X_SYS_CTRL_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 				 SII902X_SYS_CTRL_OUTPUT_MODE, output_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 		goto error_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	ret = num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) error_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 	mutex_unlock(&sii902x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) static enum drm_mode_status sii902x_mode_valid(struct drm_connector *connector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 					       struct drm_display_mode *mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	if (mode->hdisplay > 1920 || mode->vdisplay > 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 		return MODE_BAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	if (mode->clock > 165000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 		return MODE_BAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	return MODE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) static const struct drm_connector_helper_funcs sii902x_connector_helper_funcs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	.get_modes = sii902x_get_modes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	.mode_valid = sii902x_mode_valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) static void sii902x_bridge_disable(struct drm_bridge *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	struct sii902x *sii902x = bridge_to_sii902x(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	mutex_lock(&sii902x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	regmap_update_bits(sii902x->regmap, SII902X_SYS_CTRL_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 			   SII902X_SYS_CTRL_PWR_DWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 			   SII902X_SYS_CTRL_PWR_DWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	mutex_unlock(&sii902x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) static void sii902x_bridge_enable(struct drm_bridge *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	struct sii902x *sii902x = bridge_to_sii902x(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	mutex_lock(&sii902x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	regmap_update_bits(sii902x->regmap, SII902X_PWR_STATE_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 			   SII902X_AVI_POWER_STATE_MSK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 			   SII902X_AVI_POWER_STATE_D(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	regmap_update_bits(sii902x->regmap, SII902X_SYS_CTRL_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 			   SII902X_SYS_CTRL_PWR_DWN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	mutex_unlock(&sii902x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) static bool sii902x_check_embedded_format(uint32_t bus_format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	switch (bus_format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	case MEDIA_BUS_FMT_YUYV8_2X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	case MEDIA_BUS_FMT_YVYU8_2X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	case MEDIA_BUS_FMT_UYVY8_2X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	case MEDIA_BUS_FMT_VYUY8_2X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	case MEDIA_BUS_FMT_YUYV8_1X16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	case MEDIA_BUS_FMT_YVYU8_1X16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	case MEDIA_BUS_FMT_UYVY8_1X16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	case MEDIA_BUS_FMT_VYUY8_1X16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	}
^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) static void sii902x_set_embedded_sync(struct sii902x *sii902x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	unsigned char data[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	struct videomode vm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	if (!sii902x_check_embedded_format(sii902x->bus_format))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	switch (sii902x->bus_format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	case MEDIA_BUS_FMT_YUYV8_2X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	case MEDIA_BUS_FMT_YVYU8_2X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	case MEDIA_BUS_FMT_UYVY8_2X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	case MEDIA_BUS_FMT_VYUY8_2X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 		sii902x_update_bits_unlocked(sii902x->i2c, SII902X_TPI_SYNC_GEN_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 					     0x20, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	sii902x_update_bits_unlocked(sii902x->i2c, SII902X_TPI_SYNC_GEN_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 				     0x80,  0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	regmap_write(sii902x->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 		     SII902X_EMBEDDED_SYNC_EXTRACTION_REG, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	sii902x_update_bits_unlocked(sii902x->i2c, SII902X_TPI_SYNC_GEN_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 				     0x80,  0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	drm_display_mode_to_videomode(&sii902x->mode, &vm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	data[0] = vm.hfront_porch & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	data[1] = (vm.hfront_porch >> 8) & 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	data[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	data[3] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	data[4] = vm.hsync_len & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	data[5] = (vm.hsync_len >> 8) & 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	data[6] = vm.vfront_porch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	data[7] = vm.vsync_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	regmap_bulk_write(sii902x->regmap, SII902X_TPI_HBIT_TO_HSYNC, data, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	sii902x_update_bits_unlocked(sii902x->i2c, SII902X_TPI_SYNC_GEN_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 				     0x80, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	sii902x_update_bits_unlocked(sii902x->i2c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 				     SII902X_EMBEDDED_SYNC_EXTRACTION_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 				     0x40, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	regmap_update_bits(sii902x->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 			   SII902X_EMBEDDED_SYNC_EXTRACTION_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 			   SII902X_EMBEDDED_SYNC_EXTRACTION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 			   SII902X_EMBEDDED_SYNC_EXTRACTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) static void sii902x_set_format(struct sii902x *sii902x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	switch (sii902x->bus_format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	case MEDIA_BUS_FMT_YUYV8_1X16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	case MEDIA_BUS_FMT_YVYU8_1X16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	case MEDIA_BUS_FMT_UYVY8_1X16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	case MEDIA_BUS_FMT_VYUY8_1X16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	case MEDIA_BUS_FMT_YUYV8_2X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	case MEDIA_BUS_FMT_YVYU8_2X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	case MEDIA_BUS_FMT_UYVY8_2X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	case MEDIA_BUS_FMT_VYUY8_2X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 		val = SII902X_TPI_AVI_INPUT_COLORSPACE_YUV422;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	case MEDIA_BUS_FMT_YUV8_1X24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	case MEDIA_BUS_FMT_VUY8_1X24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 		val = SII902X_TPI_AVI_INPUT_COLORSPACE_YUV444;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	case MEDIA_BUS_FMT_RGB888_1X24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 		val = SII902X_TPI_AVI_INPUT_COLORSPACE_RGB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	val |= SII902X_TPI_AVI_INPUT_RANGE_AUTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	val &= ~(SII902X_TPI_AVI_INPUT_DITHER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 		 SII902X_TPI_AVI_INPUT_BITMODE_12BIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	regmap_write(sii902x->regmap, SII902X_TPI_AVI_IN_FORMAT, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	sii902x_set_embedded_sync(sii902x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) static void sii902x_bridge_mode_set(struct drm_bridge *bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 				    const struct drm_display_mode *mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 				    const struct drm_display_mode *adj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	struct sii902x *sii902x = bridge_to_sii902x(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	struct regmap *regmap = sii902x->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 	u8 buf[HDMI_INFOFRAME_SIZE(AVI)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	struct hdmi_avi_infoframe frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	u16 pixel_clock_10kHz = adj->clock / 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	int ret, vrefresh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	drm_mode_copy(&sii902x->mode, adj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	vrefresh = drm_mode_vrefresh(mode) * 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	buf[0] = pixel_clock_10kHz & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	buf[1] = pixel_clock_10kHz >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	buf[2] = vrefresh & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	buf[3] = vrefresh >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	buf[4] = adj->crtc_htotal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	buf[5] = adj->crtc_htotal >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	buf[6] = adj->crtc_vtotal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	buf[7] = adj->crtc_vtotal >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	buf[8] = SII902X_TPI_CLK_RATIO_1X | SII902X_TPI_AVI_PIXEL_REP_NONE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 		 SII902X_TPI_AVI_PIXEL_REP_BUS_24BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	switch (sii902x->bus_format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	case MEDIA_BUS_FMT_YUYV8_1X16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	case MEDIA_BUS_FMT_YVYU8_1X16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	case MEDIA_BUS_FMT_UYVY8_1X16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	case MEDIA_BUS_FMT_VYUY8_1X16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	case MEDIA_BUS_FMT_YUYV8_2X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	case MEDIA_BUS_FMT_YVYU8_2X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	case MEDIA_BUS_FMT_UYVY8_2X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	case MEDIA_BUS_FMT_VYUY8_2X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 		buf[8] |= SII902X_TPI_AVI_PIXEL_REP_RISING_EDGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	buf[9] = SII902X_TPI_AVI_INPUT_RANGE_AUTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	switch (sii902x->bus_format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	case MEDIA_BUS_FMT_YUYV8_1X16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	case MEDIA_BUS_FMT_YVYU8_1X16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	case MEDIA_BUS_FMT_UYVY8_1X16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	case MEDIA_BUS_FMT_VYUY8_1X16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	case MEDIA_BUS_FMT_YUYV8_2X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	case MEDIA_BUS_FMT_YVYU8_2X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	case MEDIA_BUS_FMT_UYVY8_2X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	case MEDIA_BUS_FMT_VYUY8_2X8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 		buf[9] |= SII902X_TPI_AVI_INPUT_COLORSPACE_YUV422;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	case MEDIA_BUS_FMT_YUV8_1X24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	case MEDIA_BUS_FMT_VUY8_1X24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 		buf[9] |= SII902X_TPI_AVI_INPUT_COLORSPACE_YUV444;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	case MEDIA_BUS_FMT_RGB888_1X24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 		buf[9] |= SII902X_TPI_AVI_INPUT_COLORSPACE_RGB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	mutex_lock(&sii902x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	ret = regmap_bulk_write(regmap, SII902X_TPI_VIDEO_DATA, buf, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	ret = drm_hdmi_avi_infoframe_from_display_mode(&frame,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 						       &sii902x->connector, adj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 		DRM_ERROR("couldn't fill AVI infoframe\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	ret = hdmi_avi_infoframe_pack(&frame, buf, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 		DRM_ERROR("failed to pack AVI infoframe: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	/* Do not send the infoframe header, but keep the CRC field. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	regmap_bulk_write(regmap, SII902X_TPI_AVI_INFOFRAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 			  buf + HDMI_INFOFRAME_HEADER_SIZE - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 			  HDMI_AVI_INFOFRAME_SIZE + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	sii902x_set_format(sii902x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	mutex_unlock(&sii902x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) static int sii902x_bridge_attach(struct drm_bridge *bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 				 enum drm_bridge_attach_flags flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	struct sii902x *sii902x = bridge_to_sii902x(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	struct drm_device *drm = bridge->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 		DRM_ERROR("Fix bridge driver to make connector optional!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	sii902x->connector.interlace_allowed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	drm_connector_helper_add(&sii902x->connector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 				 &sii902x_connector_helper_funcs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	if (!drm_core_check_feature(drm, DRIVER_ATOMIC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 		dev_err(&sii902x->i2c->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 			"sii902x driver is only compatible with DRM devices supporting atomic updates\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 		return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	ret = drm_connector_init(drm, &sii902x->connector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 				 &sii902x_connector_funcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 				 DRM_MODE_CONNECTOR_HDMIA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	if (sii902x->i2c->irq > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 		sii902x->connector.polled = DRM_CONNECTOR_POLL_HPD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 		sii902x->connector.polled = DRM_CONNECTOR_POLL_CONNECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	drm_connector_attach_encoder(&sii902x->connector, bridge->encoder);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) static const struct drm_bridge_funcs sii902x_bridge_funcs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	.attach = sii902x_bridge_attach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	.mode_set = sii902x_bridge_mode_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	.disable = sii902x_bridge_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	.enable = sii902x_bridge_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) static int sii902x_mute(struct sii902x *sii902x, bool mute)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	struct device *dev = &sii902x->i2c->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 	unsigned int val = mute ? SII902X_TPI_AUDIO_MUTE_ENABLE :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 		SII902X_TPI_AUDIO_MUTE_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 	dev_dbg(dev, "%s: %s\n", __func__, mute ? "Muted" : "Unmuted");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	return regmap_update_bits(sii902x->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 				  SII902X_TPI_AUDIO_CONFIG_BYTE2_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 				  SII902X_TPI_AUDIO_MUTE_ENABLE, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) static const int sii902x_mclk_div_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	128, 256, 384, 512, 768, 1024, 1152, 192 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) static int sii902x_select_mclk_div(u8 *i2s_config_reg, unsigned int rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 				   unsigned int mclk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	int div = mclk / rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	int distance = 100000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	u8 i, nearest = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	for (i = 0; i < ARRAY_SIZE(sii902x_mclk_div_table); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 		unsigned int d = abs(div - sii902x_mclk_div_table[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 		if (d >= distance)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 		nearest = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 		distance = d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 		if (d == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	*i2s_config_reg |= nearest << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	return sii902x_mclk_div_table[nearest];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) static const struct sii902x_sample_freq {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	u32 freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) } sii902x_sample_freq[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	{ .freq = 32000,	.val = SII902X_TPI_AUDIO_FREQ_32KHZ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	{ .freq = 44000,	.val = SII902X_TPI_AUDIO_FREQ_44KHZ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	{ .freq = 48000,	.val = SII902X_TPI_AUDIO_FREQ_48KHZ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	{ .freq = 88000,	.val = SII902X_TPI_AUDIO_FREQ_88KHZ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	{ .freq = 96000,	.val = SII902X_TPI_AUDIO_FREQ_96KHZ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	{ .freq = 176000,	.val = SII902X_TPI_AUDIO_FREQ_176KHZ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	{ .freq = 192000,	.val = SII902X_TPI_AUDIO_FREQ_192KHZ },
^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) static int sii902x_audio_hw_params(struct device *dev, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 				   struct hdmi_codec_daifmt *daifmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 				   struct hdmi_codec_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	struct sii902x *sii902x = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	u8 i2s_config_reg = SII902X_TPI_I2S_SD_DIRECTION_MSB_FIRST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	u8 config_byte2_reg = (SII902X_TPI_AUDIO_INTERFACE_I2S |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 			       SII902X_TPI_AUDIO_MUTE_ENABLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 			       SII902X_TPI_AUDIO_CODING_PCM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	u8 config_byte3_reg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	u8 infoframe_buf[HDMI_INFOFRAME_SIZE(AUDIO)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	unsigned long mclk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	if (daifmt->bit_clk_master || daifmt->frame_clk_master) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 		dev_dbg(dev, "%s: I2S master mode not supported\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	switch (daifmt->fmt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	case HDMI_I2S:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 		i2s_config_reg |= SII902X_TPI_I2S_FIRST_BIT_SHIFT_YES |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 			SII902X_TPI_I2S_SD_JUSTIFY_LEFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	case HDMI_RIGHT_J:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 		i2s_config_reg |= SII902X_TPI_I2S_SD_JUSTIFY_RIGHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	case HDMI_LEFT_J:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 		i2s_config_reg |= SII902X_TPI_I2S_SD_JUSTIFY_LEFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 		dev_dbg(dev, "%s: Unsupported i2s format %u\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 			daifmt->fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	if (daifmt->bit_clk_inv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 		i2s_config_reg |= SII902X_TPI_I2S_SCK_EDGE_FALLING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 		i2s_config_reg |= SII902X_TPI_I2S_SCK_EDGE_RISING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	if (daifmt->frame_clk_inv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 		i2s_config_reg |= SII902X_TPI_I2S_WS_POLARITY_LOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 		i2s_config_reg |= SII902X_TPI_I2S_WS_POLARITY_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	if (params->channels > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 		config_byte2_reg |= SII902X_TPI_AUDIO_LAYOUT_8_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 		config_byte2_reg |= SII902X_TPI_AUDIO_LAYOUT_2_CHANNELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	switch (params->sample_width) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 		config_byte3_reg |= SII902X_TPI_AUDIO_SAMPLE_SIZE_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	case 20:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 		config_byte3_reg |= SII902X_TPI_AUDIO_SAMPLE_SIZE_20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	case 24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	case 32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 		config_byte3_reg |= SII902X_TPI_AUDIO_SAMPLE_SIZE_24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 		dev_err(dev, "%s: Unsupported sample width %u\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 			params->sample_width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	for (i = 0; i < ARRAY_SIZE(sii902x_sample_freq); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 		if (params->sample_rate == sii902x_sample_freq[i].freq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 			config_byte3_reg |= sii902x_sample_freq[i].val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	ret = clk_prepare_enable(sii902x->audio.mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		dev_err(dev, "Enabling mclk failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	if (sii902x->audio.mclk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 		mclk_rate = clk_get_rate(sii902x->audio.mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 		ret = sii902x_select_mclk_div(&i2s_config_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 					      params->sample_rate, mclk_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 		if (mclk_rate != ret * params->sample_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 			dev_dbg(dev, "Inaccurate reference clock (%ld/%d != %u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 				mclk_rate, ret, params->sample_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	mutex_lock(&sii902x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	ret = regmap_write(sii902x->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 			   SII902X_TPI_AUDIO_CONFIG_BYTE2_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 			   config_byte2_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	ret = regmap_write(sii902x->regmap, SII902X_TPI_I2S_INPUT_CONFIG_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 			   i2s_config_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	for (i = 0; i < ARRAY_SIZE(sii902x->audio.i2s_fifo_sequence) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 		    sii902x->audio.i2s_fifo_sequence[i]; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 		regmap_write(sii902x->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 			     SII902X_TPI_I2S_ENABLE_MAPPING_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 			     sii902x->audio.i2s_fifo_sequence[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	ret = regmap_write(sii902x->regmap, SII902X_TPI_AUDIO_CONFIG_BYTE3_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 			   config_byte3_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	ret = regmap_bulk_write(sii902x->regmap, SII902X_TPI_I2S_STRM_HDR_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 				params->iec.status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 				min((size_t) SII902X_TPI_I2S_STRM_HDR_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 				    sizeof(params->iec.status)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	ret = hdmi_audio_infoframe_pack(&params->cea, infoframe_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 					sizeof(infoframe_buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 		dev_err(dev, "%s: Failed to pack audio infoframe: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 			__func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	ret = regmap_bulk_write(sii902x->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 				SII902X_TPI_MISC_INFOFRAME_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 				infoframe_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 				min(ret, SII902X_TPI_MISC_INFOFRAME_SIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	/* Decode Level 0 Packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	ret = regmap_write(sii902x->regmap, SII902X_IND_SET_PAGE, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	ret = regmap_write(sii902x->regmap, SII902X_IND_OFFSET, 0x24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	ret = regmap_write(sii902x->regmap, SII902X_IND_VALUE, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	dev_dbg(dev, "%s: hdmi audio enabled\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	mutex_unlock(&sii902x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 		clk_disable_unprepare(sii902x->audio.mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 		dev_err(dev, "%s: hdmi audio enable failed: %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 			ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) static void sii902x_audio_shutdown(struct device *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	struct sii902x *sii902x = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	mutex_lock(&sii902x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	regmap_write(sii902x->regmap, SII902X_TPI_AUDIO_CONFIG_BYTE2_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 		     SII902X_TPI_AUDIO_INTERFACE_DISABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	mutex_unlock(&sii902x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	clk_disable_unprepare(sii902x->audio.mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) static int sii902x_audio_mute(struct device *dev, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 			      bool enable, int direction)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	struct sii902x *sii902x = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	mutex_lock(&sii902x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	sii902x_mute(sii902x, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	mutex_unlock(&sii902x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) static int sii902x_audio_get_eld(struct device *dev, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 				 uint8_t *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	struct sii902x *sii902x = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	mutex_lock(&sii902x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	memcpy(buf, sii902x->connector.eld,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	       min(sizeof(sii902x->connector.eld), len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	mutex_unlock(&sii902x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) static int sii902x_audio_get_dai_id(struct snd_soc_component *component,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 				    struct device_node *endpoint)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	struct of_endpoint of_ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	ret = of_graph_parse_endpoint(endpoint, &of_ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	 * HDMI sound should be located at reg = <3>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	 * Return expected DAI index 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	if (of_ep.port == SII902X_AUDIO_PORT_INDEX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) static const struct hdmi_codec_ops sii902x_audio_codec_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	.hw_params = sii902x_audio_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	.audio_shutdown = sii902x_audio_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	.mute_stream = sii902x_audio_mute,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	.get_eld = sii902x_audio_get_eld,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	.get_dai_id = sii902x_audio_get_dai_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	.no_capture_mute = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) static int sii902x_audio_codec_init(struct sii902x *sii902x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 				    struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	static const u8 audio_fifo_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 		SII902X_TPI_I2S_CONFIG_FIFO0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 		SII902X_TPI_I2S_CONFIG_FIFO1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 		SII902X_TPI_I2S_CONFIG_FIFO2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 		SII902X_TPI_I2S_CONFIG_FIFO3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	static const u8 i2s_lane_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 		SII902X_TPI_I2S_SELECT_SD0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 		SII902X_TPI_I2S_SELECT_SD1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 		SII902X_TPI_I2S_SELECT_SD2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 		SII902X_TPI_I2S_SELECT_SD3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	struct hdmi_codec_pdata codec_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		.ops = &sii902x_audio_codec_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 		.i2s = 1, /* Only i2s support for now. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 		.spdif = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		.max_i2s_channels = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	u8 lanes[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 	int num_lanes, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	if (!of_property_read_bool(dev->of_node, "#sound-dai-cells")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 		dev_dbg(dev, "%s: No \"#sound-dai-cells\", no audio\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 			__func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	num_lanes = of_property_read_variable_u8_array(dev->of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 						       "sil,i2s-data-lanes",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 						       lanes, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 						       ARRAY_SIZE(lanes));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	if (num_lanes == -EINVAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 		dev_dbg(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 			"%s: No \"sil,i2s-data-lanes\", use default <0>\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 			__func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		num_lanes = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 		lanes[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	} else if (num_lanes < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		dev_err(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 			"%s: Error gettin \"sil,i2s-data-lanes\": %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 			__func__, num_lanes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 		return num_lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	codec_data.max_i2s_channels = 2 * num_lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	for (i = 0; i < num_lanes; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 		sii902x->audio.i2s_fifo_sequence[i] |= audio_fifo_id[i] |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 			i2s_lane_id[lanes[i]] |	SII902X_TPI_I2S_FIFO_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	sii902x->audio.mclk = devm_clk_get_optional(dev, "mclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	if (IS_ERR(sii902x->audio.mclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 		dev_err(dev, "%s: No clock (audio mclk) found: %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 			__func__, PTR_ERR(sii902x->audio.mclk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 		return PTR_ERR(sii902x->audio.mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	sii902x->audio.pdev = platform_device_register_data(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 		dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 		&codec_data, sizeof(codec_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	return PTR_ERR_OR_ZERO(sii902x->audio.pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) static const struct regmap_range sii902x_volatile_ranges[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	{ .range_min = 0, .range_max = 0xff },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) static const struct regmap_access_table sii902x_volatile_table = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	.yes_ranges = sii902x_volatile_ranges,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	.n_yes_ranges = ARRAY_SIZE(sii902x_volatile_ranges),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) static const struct regmap_config sii902x_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	.reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	.val_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	.disable_locking = true, /* struct sii902x mutex should be enough */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	.max_register = SII902X_TPI_MISC_INFOFRAME_END,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	.volatile_table = &sii902x_volatile_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	.cache_type = REGCACHE_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) static irqreturn_t sii902x_interrupt(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	struct sii902x *sii902x = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	unsigned int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 	mutex_lock(&sii902x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	regmap_read(sii902x->regmap, SII902X_INT_STATUS, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	regmap_write(sii902x->regmap, SII902X_INT_STATUS, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	mutex_unlock(&sii902x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	if ((status & SII902X_HOTPLUG_EVENT) && sii902x->bridge.dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 		drm_helper_hpd_irq_event(sii902x->bridge.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)  * The purpose of sii902x_i2c_bypass_select is to enable the pass through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)  * mode of the HDMI transmitter. Do not use regmap from within this function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)  * only use sii902x_*_unlocked functions to read/modify/write registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)  * We are holding the parent adapter lock here, keep this in mind before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)  * adding more i2c transactions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)  * Also, since SII902X_SYS_CTRL_DATA is used with regmap_update_bits elsewhere
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)  * in this driver, we need to make sure that we only touch 0x1A[2:1] from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)  * within sii902x_i2c_bypass_select and sii902x_i2c_bypass_deselect, and that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)  * we leave the remaining bits as we have found them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) static int sii902x_i2c_bypass_select(struct i2c_mux_core *mux, u32 chan_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	struct sii902x *sii902x = i2c_mux_priv(mux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	struct device *dev = &sii902x->i2c->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	ret = sii902x_update_bits_unlocked(sii902x->i2c, SII902X_SYS_CTRL_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 					   SII902X_SYS_CTRL_DDC_BUS_REQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 					   SII902X_SYS_CTRL_DDC_BUS_REQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	timeout = jiffies +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 		  msecs_to_jiffies(SII902X_I2C_BUS_ACQUISITION_TIMEOUT_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 		ret = sii902x_read_unlocked(sii902x->i2c, SII902X_SYS_CTRL_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 					    &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	} while (!(status & SII902X_SYS_CTRL_DDC_BUS_GRTD) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 		 time_before(jiffies, timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	if (!(status & SII902X_SYS_CTRL_DDC_BUS_GRTD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 		dev_err(dev, "Failed to acquire the i2c bus\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 		return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	return sii902x_write_unlocked(sii902x->i2c, SII902X_SYS_CTRL_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 				      status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)  * The purpose of sii902x_i2c_bypass_deselect is to disable the pass through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)  * mode of the HDMI transmitter. Do not use regmap from within this function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)  * only use sii902x_*_unlocked functions to read/modify/write registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)  * We are holding the parent adapter lock here, keep this in mind before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)  * adding more i2c transactions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)  * Also, since SII902X_SYS_CTRL_DATA is used with regmap_update_bits elsewhere
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)  * in this driver, we need to make sure that we only touch 0x1A[2:1] from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)  * within sii902x_i2c_bypass_select and sii902x_i2c_bypass_deselect, and that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)  * we leave the remaining bits as we have found them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) static int sii902x_i2c_bypass_deselect(struct i2c_mux_core *mux, u32 chan_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	struct sii902x *sii902x = i2c_mux_priv(mux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	struct device *dev = &sii902x->i2c->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	unsigned int retries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	 * When the HDMI transmitter is in pass through mode, we need an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	 * (undocumented) additional delay between STOP and START conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 	 * to guarantee the bus won't get stuck.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	udelay(30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	 * Sometimes the I2C bus can stall after failure to use the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	 * EDID channel. Retry a few times to see if things clear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	 * up, else continue anyway.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	retries = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 		ret = sii902x_read_unlocked(sii902x->i2c, SII902X_SYS_CTRL_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 					    &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 		retries--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	} while (ret && retries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 		dev_err(dev, "failed to read status (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 	ret = sii902x_update_bits_unlocked(sii902x->i2c, SII902X_SYS_CTRL_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 					   SII902X_SYS_CTRL_DDC_BUS_REQ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 					   SII902X_SYS_CTRL_DDC_BUS_GRTD, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	timeout = jiffies +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 		  msecs_to_jiffies(SII902X_I2C_BUS_ACQUISITION_TIMEOUT_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 		ret = sii902x_read_unlocked(sii902x->i2c, SII902X_SYS_CTRL_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 					    &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	} while (status & (SII902X_SYS_CTRL_DDC_BUS_REQ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 			   SII902X_SYS_CTRL_DDC_BUS_GRTD) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 		 time_before(jiffies, timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	if (status & (SII902X_SYS_CTRL_DDC_BUS_REQ |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 		      SII902X_SYS_CTRL_DDC_BUS_GRTD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 		dev_err(dev, "failed to release the i2c bus\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 		return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) static const struct drm_bridge_timings default_sii902x_timings = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	.input_bus_flags = DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 		 | DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 		 | DRM_BUS_FLAG_DE_HIGH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) static int sii902x_init(struct sii902x *sii902x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 	struct device *dev = &sii902x->i2c->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 	unsigned int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	u8 chipid[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	sii902x_reset(sii902x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	ret = regmap_write(sii902x->regmap, SII902X_REG_TPI_RQB, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 		dev_err(dev, "enable TPI mode failed %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	ret = regmap_bulk_read(sii902x->regmap, SII902X_REG_CHIPID(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 			       &chipid, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 		dev_err(dev, "regmap_read failed %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 	if (chipid[0] != 0xb0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 		dev_err(dev, "Invalid chipid: %02x (expecting 0xb0)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 			chipid[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	/* Clear all pending interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	regmap_read(sii902x->regmap, SII902X_INT_STATUS, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	regmap_write(sii902x->regmap, SII902X_INT_STATUS, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	if (sii902x->i2c->irq > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 		regmap_write(sii902x->regmap, SII902X_INT_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 			     SII902X_HOTPLUG_EVENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 		ret = devm_request_threaded_irq(dev, sii902x->i2c->irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 						sii902x_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 						IRQF_TRIGGER_FALLING |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 						IRQF_ONESHOT, dev_name(dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 						sii902x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 		if (ret)
^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) 	sii902x->bridge.funcs = &sii902x_bridge_funcs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	sii902x->bridge.of_node = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 	sii902x->bridge.timings = &default_sii902x_timings;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	drm_bridge_add(&sii902x->bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 	sii902x_audio_codec_init(sii902x, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 	i2c_set_clientdata(sii902x->i2c, sii902x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 	sii902x->i2cmux = i2c_mux_alloc(sii902x->i2c->adapter, dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 					1, 0, I2C_MUX_GATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 					sii902x_i2c_bypass_select,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 					sii902x_i2c_bypass_deselect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	if (!sii902x->i2cmux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	sii902x->i2cmux->priv = sii902x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	return i2c_mux_add_adapter(sii902x->i2cmux, 0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) static int sii902x_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 			 const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	struct device *dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	struct sii902x *sii902x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	ret = i2c_check_functionality(client->adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 				      I2C_FUNC_SMBUS_BYTE_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 	if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 		dev_err(dev, "I2C adapter not suitable\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 	sii902x = devm_kzalloc(dev, sizeof(*sii902x), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 	if (!sii902x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 	sii902x->i2c = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 	sii902x->regmap = devm_regmap_init_i2c(client, &sii902x_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	if (IS_ERR(sii902x->regmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 		return PTR_ERR(sii902x->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 	sii902x->reset_gpio = devm_gpiod_get_optional(dev, "reset",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 						      GPIOD_OUT_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 	if (IS_ERR(sii902x->reset_gpio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 		dev_err(dev, "Failed to retrieve/request reset gpio: %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 			PTR_ERR(sii902x->reset_gpio));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 		return PTR_ERR(sii902x->reset_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 	sii902x->enable_gpio = devm_gpiod_get_optional(dev, "enable",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 						       GPIOD_OUT_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 	if (IS_ERR(sii902x->enable_gpio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 		dev_err(dev, "Failed to retrieve/request enable gpio: %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 			PTR_ERR(sii902x->enable_gpio));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 		return PTR_ERR(sii902x->enable_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	} else if (sii902x->enable_gpio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 		gpiod_direction_output(sii902x->enable_gpio, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 		usleep_range(1500, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 	ret = of_property_read_u32(dev->of_node, "bus-format", &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 		sii902x->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 		switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 		case FORMAT_RGB_INPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 			sii902x->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 		case FORMAT_YCBCR422_INPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 			sii902x->bus_format = MEDIA_BUS_FMT_YUYV8_1X16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 		case FORMAT_YCBCR444_INPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 			sii902x->bus_format = MEDIA_BUS_FMT_YUV8_1X24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 			sii902x->bus_format = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 			break;
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 	mutex_init(&sii902x->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	sii902x->supplies[0].supply = "iovcc";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 	sii902x->supplies[1].supply = "cvcc12";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(sii902x->supplies),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 				      sii902x->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 	ret = regulator_bulk_enable(ARRAY_SIZE(sii902x->supplies),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 				    sii902x->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 		dev_err_probe(dev, ret, "Failed to enable supplies");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	ret = sii902x_init(sii902x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 		dev_err(dev, "Failed to init sii902x %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 		regulator_bulk_disable(ARRAY_SIZE(sii902x->supplies),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 				       sii902x->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) static int sii902x_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 	struct sii902x *sii902x = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 	i2c_mux_del_adapters(sii902x->i2cmux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 	drm_bridge_remove(&sii902x->bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 	regulator_bulk_disable(ARRAY_SIZE(sii902x->supplies),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 			       sii902x->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) static const struct of_device_id sii902x_dt_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	{ .compatible = "sil,sii9022", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) MODULE_DEVICE_TABLE(of, sii902x_dt_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) static const struct i2c_device_id sii902x_i2c_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 	{ "sii9022", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) MODULE_DEVICE_TABLE(i2c, sii902x_i2c_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) static struct i2c_driver sii902x_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	.probe = sii902x_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	.remove = sii902x_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 		.name = "sii902x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 		.of_match_table = sii902x_dt_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	.id_table = sii902x_i2c_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) module_i2c_driver(sii902x_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) MODULE_AUTHOR("Boris Brezillon <boris.brezillon@free-electrons.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) MODULE_DESCRIPTION("SII902x RGB -> HDMI bridges");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) MODULE_LICENSE("GPL");