1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
228cae868SHans Verkuil /*
3cf293a4fSAlexander A. Klimov  * Copyright (C) 2010-2013 Bluecherry, LLC <https://www.bluecherrydvr.com>
428cae868SHans Verkuil  *
528cae868SHans Verkuil  * Original author:
628cae868SHans Verkuil  * Ben Collins <bcollins@ubuntu.com>
728cae868SHans Verkuil  *
828cae868SHans Verkuil  * Additional work by:
928cae868SHans Verkuil  * John Brooks <john.brooks@bluecherry.net>
1028cae868SHans Verkuil  */
1128cae868SHans Verkuil 
1228cae868SHans Verkuil #include <linux/kernel.h>
1328cae868SHans Verkuil #include <linux/font.h>
1428cae868SHans Verkuil #include <linux/bitrev.h>
1528cae868SHans Verkuil #include <linux/slab.h>
1628cae868SHans Verkuil 
1728cae868SHans Verkuil #include "solo6x10.h"
1828cae868SHans Verkuil 
1928cae868SHans Verkuil #define VI_PROG_HSIZE			(1280 - 16)
2028cae868SHans Verkuil #define VI_PROG_VSIZE			(1024 - 16)
2128cae868SHans Verkuil 
2228cae868SHans Verkuil #define IRQ_LEVEL			2
2328cae868SHans Verkuil 
solo_capture_config(struct solo_dev * solo_dev)2428cae868SHans Verkuil static void solo_capture_config(struct solo_dev *solo_dev)
2528cae868SHans Verkuil {
2628cae868SHans Verkuil 	unsigned long height;
2728cae868SHans Verkuil 	unsigned long width;
2828cae868SHans Verkuil 	void *buf;
2928cae868SHans Verkuil 	int i;
3028cae868SHans Verkuil 
3128cae868SHans Verkuil 	solo_reg_write(solo_dev, SOLO_CAP_BASE,
3228cae868SHans Verkuil 		       SOLO_CAP_MAX_PAGE((SOLO_CAP_EXT_SIZE(solo_dev)
3328cae868SHans Verkuil 					  - SOLO_CAP_PAGE_SIZE) >> 16)
3428cae868SHans Verkuil 		       | SOLO_CAP_BASE_ADDR(SOLO_CAP_EXT_ADDR(solo_dev) >> 16));
3528cae868SHans Verkuil 
3628cae868SHans Verkuil 	/* XXX: Undocumented bits at b17 and b24 */
3728cae868SHans Verkuil 	if (solo_dev->type == SOLO_DEV_6110) {
3828cae868SHans Verkuil 		/* NOTE: Ref driver has (62 << 24) here as well, but it causes
3928cae868SHans Verkuil 		 * wacked out frame timing on 4-port 6110. */
4028cae868SHans Verkuil 		solo_reg_write(solo_dev, SOLO_CAP_BTW,
4128cae868SHans Verkuil 			       (1 << 17) | SOLO_CAP_PROG_BANDWIDTH(2) |
4228cae868SHans Verkuil 			       SOLO_CAP_MAX_BANDWIDTH(36));
4328cae868SHans Verkuil 	} else {
4428cae868SHans Verkuil 		solo_reg_write(solo_dev, SOLO_CAP_BTW,
4528cae868SHans Verkuil 			       (1 << 17) | SOLO_CAP_PROG_BANDWIDTH(2) |
4628cae868SHans Verkuil 			       SOLO_CAP_MAX_BANDWIDTH(32));
4728cae868SHans Verkuil 	}
4828cae868SHans Verkuil 
4928cae868SHans Verkuil 	/* Set scale 1, 9 dimension */
5028cae868SHans Verkuil 	width = solo_dev->video_hsize;
5128cae868SHans Verkuil 	height = solo_dev->video_vsize;
5228cae868SHans Verkuil 	solo_reg_write(solo_dev, SOLO_DIM_SCALE1,
5328cae868SHans Verkuil 		       SOLO_DIM_H_MB_NUM(width / 16) |
5428cae868SHans Verkuil 		       SOLO_DIM_V_MB_NUM_FRAME(height / 8) |
5528cae868SHans Verkuil 		       SOLO_DIM_V_MB_NUM_FIELD(height / 16));
5628cae868SHans Verkuil 
5728cae868SHans Verkuil 	/* Set scale 2, 10 dimension */
5828cae868SHans Verkuil 	width = solo_dev->video_hsize / 2;
5928cae868SHans Verkuil 	height = solo_dev->video_vsize;
6028cae868SHans Verkuil 	solo_reg_write(solo_dev, SOLO_DIM_SCALE2,
6128cae868SHans Verkuil 		       SOLO_DIM_H_MB_NUM(width / 16) |
6228cae868SHans Verkuil 		       SOLO_DIM_V_MB_NUM_FRAME(height / 8) |
6328cae868SHans Verkuil 		       SOLO_DIM_V_MB_NUM_FIELD(height / 16));
6428cae868SHans Verkuil 
6528cae868SHans Verkuil 	/* Set scale 3, 11 dimension */
6628cae868SHans Verkuil 	width = solo_dev->video_hsize / 2;
6728cae868SHans Verkuil 	height = solo_dev->video_vsize / 2;
6828cae868SHans Verkuil 	solo_reg_write(solo_dev, SOLO_DIM_SCALE3,
6928cae868SHans Verkuil 		       SOLO_DIM_H_MB_NUM(width / 16) |
7028cae868SHans Verkuil 		       SOLO_DIM_V_MB_NUM_FRAME(height / 8) |
7128cae868SHans Verkuil 		       SOLO_DIM_V_MB_NUM_FIELD(height / 16));
7228cae868SHans Verkuil 
7328cae868SHans Verkuil 	/* Set scale 4, 12 dimension */
7428cae868SHans Verkuil 	width = solo_dev->video_hsize / 3;
7528cae868SHans Verkuil 	height = solo_dev->video_vsize / 3;
7628cae868SHans Verkuil 	solo_reg_write(solo_dev, SOLO_DIM_SCALE4,
7728cae868SHans Verkuil 		       SOLO_DIM_H_MB_NUM(width / 16) |
7828cae868SHans Verkuil 		       SOLO_DIM_V_MB_NUM_FRAME(height / 8) |
7928cae868SHans Verkuil 		       SOLO_DIM_V_MB_NUM_FIELD(height / 16));
8028cae868SHans Verkuil 
8128cae868SHans Verkuil 	/* Set scale 5, 13 dimension */
8228cae868SHans Verkuil 	width = solo_dev->video_hsize / 4;
8328cae868SHans Verkuil 	height = solo_dev->video_vsize / 2;
8428cae868SHans Verkuil 	solo_reg_write(solo_dev, SOLO_DIM_SCALE5,
8528cae868SHans Verkuil 		       SOLO_DIM_H_MB_NUM(width / 16) |
8628cae868SHans Verkuil 		       SOLO_DIM_V_MB_NUM_FRAME(height / 8) |
8728cae868SHans Verkuil 		       SOLO_DIM_V_MB_NUM_FIELD(height / 16));
8828cae868SHans Verkuil 
8928cae868SHans Verkuil 	/* Progressive */
9028cae868SHans Verkuil 	width = VI_PROG_HSIZE;
9128cae868SHans Verkuil 	height = VI_PROG_VSIZE;
9228cae868SHans Verkuil 	solo_reg_write(solo_dev, SOLO_DIM_PROG,
9328cae868SHans Verkuil 		       SOLO_DIM_H_MB_NUM(width / 16) |
9428cae868SHans Verkuil 		       SOLO_DIM_V_MB_NUM_FRAME(height / 16) |
9528cae868SHans Verkuil 		       SOLO_DIM_V_MB_NUM_FIELD(height / 16));
9628cae868SHans Verkuil 
9728cae868SHans Verkuil 	/* Clear OSD */
9828cae868SHans Verkuil 	solo_reg_write(solo_dev, SOLO_VE_OSD_CH, 0);
9928cae868SHans Verkuil 	solo_reg_write(solo_dev, SOLO_VE_OSD_BASE, SOLO_EOSD_EXT_ADDR >> 16);
10028cae868SHans Verkuil 	solo_reg_write(solo_dev, SOLO_VE_OSD_CLR,
10128cae868SHans Verkuil 		       0xF0 << 16 | 0x80 << 8 | 0x80);
10228cae868SHans Verkuil 
10328cae868SHans Verkuil 	if (solo_dev->type == SOLO_DEV_6010)
10428cae868SHans Verkuil 		solo_reg_write(solo_dev, SOLO_VE_OSD_OPT,
10528cae868SHans Verkuil 			       SOLO_VE_OSD_H_SHADOW | SOLO_VE_OSD_V_SHADOW);
10628cae868SHans Verkuil 	else
10728cae868SHans Verkuil 		solo_reg_write(solo_dev, SOLO_VE_OSD_OPT, SOLO_VE_OSD_V_DOUBLE
10828cae868SHans Verkuil 			       | SOLO_VE_OSD_H_SHADOW | SOLO_VE_OSD_V_SHADOW);
10928cae868SHans Verkuil 
11028cae868SHans Verkuil 	/* Clear OSG buffer */
11128cae868SHans Verkuil 	buf = kzalloc(SOLO_EOSD_EXT_SIZE(solo_dev), GFP_KERNEL);
11228cae868SHans Verkuil 	if (!buf)
11328cae868SHans Verkuil 		return;
11428cae868SHans Verkuil 
11528cae868SHans Verkuil 	for (i = 0; i < solo_dev->nr_chans; i++) {
11628cae868SHans Verkuil 		solo_p2m_dma(solo_dev, 1, buf,
11728cae868SHans Verkuil 			     SOLO_EOSD_EXT_ADDR +
11828cae868SHans Verkuil 			     (SOLO_EOSD_EXT_SIZE(solo_dev) * i),
11928cae868SHans Verkuil 			     SOLO_EOSD_EXT_SIZE(solo_dev), 0, 0);
12028cae868SHans Verkuil 	}
12128cae868SHans Verkuil 	kfree(buf);
12228cae868SHans Verkuil }
12328cae868SHans Verkuil 
12428cae868SHans Verkuil #define SOLO_OSD_WRITE_SIZE (16 * OSD_TEXT_MAX)
12528cae868SHans Verkuil 
12628cae868SHans Verkuil /* Should be called with enable_lock held */
solo_osd_print(struct solo_enc_dev * solo_enc)12728cae868SHans Verkuil int solo_osd_print(struct solo_enc_dev *solo_enc)
12828cae868SHans Verkuil {
12928cae868SHans Verkuil 	struct solo_dev *solo_dev = solo_enc->solo_dev;
1308a4d9a9cSIsmael Luceno 	u8 *str = solo_enc->osd_text;
13128cae868SHans Verkuil 	u8 *buf = solo_enc->osd_buf;
13228cae868SHans Verkuil 	u32 reg;
13328cae868SHans Verkuil 	const struct font_desc *vga = find_font("VGA8x16");
1348a4d9a9cSIsmael Luceno 	const u8 *vga_data;
13528cae868SHans Verkuil 	int i, j;
13628cae868SHans Verkuil 
13728cae868SHans Verkuil 	if (WARN_ON_ONCE(!vga))
13828cae868SHans Verkuil 		return -ENODEV;
13928cae868SHans Verkuil 
14028cae868SHans Verkuil 	reg = solo_reg_read(solo_dev, SOLO_VE_OSD_CH);
14128cae868SHans Verkuil 	if (!*str) {
14228cae868SHans Verkuil 		/* Disable OSD on this channel */
14328cae868SHans Verkuil 		reg &= ~(1 << solo_enc->ch);
14428cae868SHans Verkuil 		goto out;
14528cae868SHans Verkuil 	}
14628cae868SHans Verkuil 
14728cae868SHans Verkuil 	memset(buf, 0, SOLO_OSD_WRITE_SIZE);
1488a4d9a9cSIsmael Luceno 	vga_data = (const u8 *)vga->data;
14928cae868SHans Verkuil 
15028cae868SHans Verkuil 	for (i = 0; *str; i++, str++) {
15128cae868SHans Verkuil 		for (j = 0; j < 16; j++) {
15228cae868SHans Verkuil 			buf[(j << 1) | (i & 1) | ((i & ~1) << 4)] =
15328cae868SHans Verkuil 			    bitrev8(vga_data[(*str << 4) | j]);
15428cae868SHans Verkuil 		}
15528cae868SHans Verkuil 	}
15628cae868SHans Verkuil 
15728cae868SHans Verkuil 	solo_p2m_dma(solo_dev, 1, buf,
15828cae868SHans Verkuil 		     SOLO_EOSD_EXT_ADDR_CHAN(solo_dev, solo_enc->ch),
15928cae868SHans Verkuil 		     SOLO_OSD_WRITE_SIZE, 0, 0);
16028cae868SHans Verkuil 
16128cae868SHans Verkuil 	/* Enable OSD on this channel */
16228cae868SHans Verkuil 	reg |= (1 << solo_enc->ch);
16328cae868SHans Verkuil 
16428cae868SHans Verkuil out:
16528cae868SHans Verkuil 	solo_reg_write(solo_dev, SOLO_VE_OSD_CH, reg);
16628cae868SHans Verkuil 	return 0;
16728cae868SHans Verkuil }
16828cae868SHans Verkuil 
169cba862dcSMauro Carvalho Chehab /*
17028cae868SHans Verkuil  * Set channel Quality Profile (0-3).
17128cae868SHans Verkuil  */
solo_s_jpeg_qp(struct solo_dev * solo_dev,unsigned int ch,unsigned int qp)17228cae868SHans Verkuil void solo_s_jpeg_qp(struct solo_dev *solo_dev, unsigned int ch,
17328cae868SHans Verkuil 		    unsigned int qp)
17428cae868SHans Verkuil {
17528cae868SHans Verkuil 	unsigned long flags;
17628cae868SHans Verkuil 	unsigned int idx, reg;
17728cae868SHans Verkuil 
17828cae868SHans Verkuil 	if ((ch > 31) || (qp > 3))
17928cae868SHans Verkuil 		return;
18028cae868SHans Verkuil 
18128cae868SHans Verkuil 	if (solo_dev->type == SOLO_DEV_6010)
18228cae868SHans Verkuil 		return;
18328cae868SHans Verkuil 
18428cae868SHans Verkuil 	if (ch < 16) {
18528cae868SHans Verkuil 		idx = 0;
18628cae868SHans Verkuil 		reg = SOLO_VE_JPEG_QP_CH_L;
18728cae868SHans Verkuil 	} else {
18828cae868SHans Verkuil 		ch -= 16;
18928cae868SHans Verkuil 		idx = 1;
19028cae868SHans Verkuil 		reg = SOLO_VE_JPEG_QP_CH_H;
19128cae868SHans Verkuil 	}
19228cae868SHans Verkuil 	ch *= 2;
19328cae868SHans Verkuil 
19428cae868SHans Verkuil 	spin_lock_irqsave(&solo_dev->jpeg_qp_lock, flags);
19528cae868SHans Verkuil 
19628cae868SHans Verkuil 	solo_dev->jpeg_qp[idx] &= ~(3 << ch);
19728cae868SHans Verkuil 	solo_dev->jpeg_qp[idx] |= (qp & 3) << ch;
19828cae868SHans Verkuil 
19928cae868SHans Verkuil 	solo_reg_write(solo_dev, reg, solo_dev->jpeg_qp[idx]);
20028cae868SHans Verkuil 
20128cae868SHans Verkuil 	spin_unlock_irqrestore(&solo_dev->jpeg_qp_lock, flags);
20228cae868SHans Verkuil }
20328cae868SHans Verkuil 
solo_g_jpeg_qp(struct solo_dev * solo_dev,unsigned int ch)20428cae868SHans Verkuil int solo_g_jpeg_qp(struct solo_dev *solo_dev, unsigned int ch)
20528cae868SHans Verkuil {
20628cae868SHans Verkuil 	int idx;
20728cae868SHans Verkuil 
20828cae868SHans Verkuil 	if (solo_dev->type == SOLO_DEV_6010)
20928cae868SHans Verkuil 		return 2;
21028cae868SHans Verkuil 
21128cae868SHans Verkuil 	if (WARN_ON_ONCE(ch > 31))
21228cae868SHans Verkuil 		return 2;
21328cae868SHans Verkuil 
21428cae868SHans Verkuil 	if (ch < 16) {
21528cae868SHans Verkuil 		idx = 0;
21628cae868SHans Verkuil 	} else {
21728cae868SHans Verkuil 		ch -= 16;
21828cae868SHans Verkuil 		idx = 1;
21928cae868SHans Verkuil 	}
22028cae868SHans Verkuil 	ch *= 2;
22128cae868SHans Verkuil 
22228cae868SHans Verkuil 	return (solo_dev->jpeg_qp[idx] >> ch) & 3;
22328cae868SHans Verkuil }
22428cae868SHans Verkuil 
22528cae868SHans Verkuil #define SOLO_QP_INIT 0xaaaaaaaa
22628cae868SHans Verkuil 
solo_jpeg_config(struct solo_dev * solo_dev)22728cae868SHans Verkuil static void solo_jpeg_config(struct solo_dev *solo_dev)
22828cae868SHans Verkuil {
22928cae868SHans Verkuil 	if (solo_dev->type == SOLO_DEV_6010) {
23028cae868SHans Verkuil 		solo_reg_write(solo_dev, SOLO_VE_JPEG_QP_TBL,
23128cae868SHans Verkuil 			       (2 << 24) | (2 << 16) | (2 << 8) | 2);
23228cae868SHans Verkuil 	} else {
23328cae868SHans Verkuil 		solo_reg_write(solo_dev, SOLO_VE_JPEG_QP_TBL,
23428cae868SHans Verkuil 			       (4 << 24) | (3 << 16) | (2 << 8) | 1);
23528cae868SHans Verkuil 	}
23628cae868SHans Verkuil 
23728cae868SHans Verkuil 	spin_lock_init(&solo_dev->jpeg_qp_lock);
23828cae868SHans Verkuil 
23928cae868SHans Verkuil 	/* Initialize Quality Profile for all channels */
24028cae868SHans Verkuil 	solo_dev->jpeg_qp[0] = solo_dev->jpeg_qp[1] = SOLO_QP_INIT;
24128cae868SHans Verkuil 	solo_reg_write(solo_dev, SOLO_VE_JPEG_QP_CH_L, SOLO_QP_INIT);
24228cae868SHans Verkuil 	solo_reg_write(solo_dev, SOLO_VE_JPEG_QP_CH_H, SOLO_QP_INIT);
24328cae868SHans Verkuil 
24428cae868SHans Verkuil 	solo_reg_write(solo_dev, SOLO_VE_JPEG_CFG,
24528cae868SHans Verkuil 		(SOLO_JPEG_EXT_SIZE(solo_dev) & 0xffff0000) |
24628cae868SHans Verkuil 		((SOLO_JPEG_EXT_ADDR(solo_dev) >> 16) & 0x0000ffff));
24728cae868SHans Verkuil 	solo_reg_write(solo_dev, SOLO_VE_JPEG_CTRL, 0xffffffff);
24828cae868SHans Verkuil 	if (solo_dev->type == SOLO_DEV_6110) {
24928cae868SHans Verkuil 		solo_reg_write(solo_dev, SOLO_VE_JPEG_CFG1,
25028cae868SHans Verkuil 			       (0 << 16) | (30 << 8) | 60);
25128cae868SHans Verkuil 	}
25228cae868SHans Verkuil }
25328cae868SHans Verkuil 
solo_mp4e_config(struct solo_dev * solo_dev)25428cae868SHans Verkuil static void solo_mp4e_config(struct solo_dev *solo_dev)
25528cae868SHans Verkuil {
25628cae868SHans Verkuil 	int i;
25728cae868SHans Verkuil 	u32 cfg;
25828cae868SHans Verkuil 
25928cae868SHans Verkuil 	solo_reg_write(solo_dev, SOLO_VE_CFG0,
26028cae868SHans Verkuil 		       SOLO_VE_INTR_CTRL(IRQ_LEVEL) |
26128cae868SHans Verkuil 		       SOLO_VE_BLOCK_SIZE(SOLO_MP4E_EXT_SIZE(solo_dev) >> 16) |
26228cae868SHans Verkuil 		       SOLO_VE_BLOCK_BASE(SOLO_MP4E_EXT_ADDR(solo_dev) >> 16));
26328cae868SHans Verkuil 
26428cae868SHans Verkuil 
26528cae868SHans Verkuil 	cfg = SOLO_VE_BYTE_ALIGN(2) | SOLO_VE_INSERT_INDEX
26628cae868SHans Verkuil 		| SOLO_VE_MOTION_MODE(0);
26728cae868SHans Verkuil 	if (solo_dev->type != SOLO_DEV_6010) {
26828cae868SHans Verkuil 		cfg |= SOLO_VE_MPEG_SIZE_H(
26928cae868SHans Verkuil 			(SOLO_MP4E_EXT_SIZE(solo_dev) >> 24) & 0x0f);
27028cae868SHans Verkuil 		cfg |= SOLO_VE_JPEG_SIZE_H(
27128cae868SHans Verkuil 			(SOLO_JPEG_EXT_SIZE(solo_dev) >> 24) & 0x0f);
27228cae868SHans Verkuil 	}
27328cae868SHans Verkuil 	solo_reg_write(solo_dev, SOLO_VE_CFG1, cfg);
27428cae868SHans Verkuil 
27528cae868SHans Verkuil 	solo_reg_write(solo_dev, SOLO_VE_WMRK_POLY, 0);
27628cae868SHans Verkuil 	solo_reg_write(solo_dev, SOLO_VE_VMRK_INIT_KEY, 0);
27728cae868SHans Verkuil 	solo_reg_write(solo_dev, SOLO_VE_WMRK_STRL, 0);
27828cae868SHans Verkuil 	if (solo_dev->type == SOLO_DEV_6110)
27928cae868SHans Verkuil 		solo_reg_write(solo_dev, SOLO_VE_WMRK_ENABLE, 0);
28028cae868SHans Verkuil 	solo_reg_write(solo_dev, SOLO_VE_ENCRYP_POLY, 0);
28128cae868SHans Verkuil 	solo_reg_write(solo_dev, SOLO_VE_ENCRYP_INIT, 0);
28228cae868SHans Verkuil 
28328cae868SHans Verkuil 	solo_reg_write(solo_dev, SOLO_VE_ATTR,
28428cae868SHans Verkuil 		       SOLO_VE_LITTLE_ENDIAN |
28528cae868SHans Verkuil 		       SOLO_COMP_ATTR_FCODE(1) |
28628cae868SHans Verkuil 		       SOLO_COMP_TIME_INC(0) |
28728cae868SHans Verkuil 		       SOLO_COMP_TIME_WIDTH(15) |
28828cae868SHans Verkuil 		       SOLO_DCT_INTERVAL(solo_dev->type == SOLO_DEV_6010 ? 9 : 10));
28928cae868SHans Verkuil 
29028cae868SHans Verkuil 	for (i = 0; i < solo_dev->nr_chans; i++) {
29128cae868SHans Verkuil 		solo_reg_write(solo_dev, SOLO_VE_CH_REF_BASE(i),
29228cae868SHans Verkuil 			       (SOLO_EREF_EXT_ADDR(solo_dev) +
29328cae868SHans Verkuil 			       (i * SOLO_EREF_EXT_SIZE)) >> 16);
29428cae868SHans Verkuil 		solo_reg_write(solo_dev, SOLO_VE_CH_REF_BASE_E(i),
29528cae868SHans Verkuil 			       (SOLO_EREF_EXT_ADDR(solo_dev) +
29628cae868SHans Verkuil 			       ((i + 16) * SOLO_EREF_EXT_SIZE)) >> 16);
29728cae868SHans Verkuil 	}
29828cae868SHans Verkuil 
29928cae868SHans Verkuil 	if (solo_dev->type == SOLO_DEV_6110) {
30028cae868SHans Verkuil 		solo_reg_write(solo_dev, SOLO_VE_COMPT_MOT, 0x00040008);
30128cae868SHans Verkuil 	} else {
30228cae868SHans Verkuil 		for (i = 0; i < solo_dev->nr_chans; i++)
30328cae868SHans Verkuil 			solo_reg_write(solo_dev, SOLO_VE_CH_MOT(i), 0x100);
30428cae868SHans Verkuil 	}
30528cae868SHans Verkuil }
30628cae868SHans Verkuil 
solo_enc_init(struct solo_dev * solo_dev)30728cae868SHans Verkuil int solo_enc_init(struct solo_dev *solo_dev)
30828cae868SHans Verkuil {
30928cae868SHans Verkuil 	int i;
31028cae868SHans Verkuil 
31128cae868SHans Verkuil 	solo_capture_config(solo_dev);
31228cae868SHans Verkuil 	solo_mp4e_config(solo_dev);
31328cae868SHans Verkuil 	solo_jpeg_config(solo_dev);
31428cae868SHans Verkuil 
31528cae868SHans Verkuil 	for (i = 0; i < solo_dev->nr_chans; i++) {
31628cae868SHans Verkuil 		solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(i), 0);
31728cae868SHans Verkuil 		solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(i), 0);
31828cae868SHans Verkuil 	}
31928cae868SHans Verkuil 
32028cae868SHans Verkuil 	return 0;
32128cae868SHans Verkuil }
32228cae868SHans Verkuil 
solo_enc_exit(struct solo_dev * solo_dev)32328cae868SHans Verkuil void solo_enc_exit(struct solo_dev *solo_dev)
32428cae868SHans Verkuil {
32528cae868SHans Verkuil 	int i;
32628cae868SHans Verkuil 
32728cae868SHans Verkuil 	for (i = 0; i < solo_dev->nr_chans; i++) {
32828cae868SHans Verkuil 		solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(i), 0);
32928cae868SHans Verkuil 		solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(i), 0);
33028cae868SHans Verkuil 	}
33128cae868SHans Verkuil }
332