brintos

brintos / linux-shallow public Read only

0
0
Text · 2.5 KiB · aba5940 Raw
130 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * cxd2880_devio_spi.c4 * Sony CXD2880 DVB-T2/T tuner + demodulator driver5 * I/O interface via SPI6 *7 * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation8 */9 10#include "cxd2880_devio_spi.h"11 12#define BURST_WRITE_MAX 12813 14static int cxd2880_io_spi_read_reg(struct cxd2880_io *io,15				   enum cxd2880_io_tgt tgt,16				   u8 sub_address, u8 *data,17				   u32 size)18{19	int ret = 0;20	struct cxd2880_spi *spi = NULL;21	u8 send_data[6];22	u8 *read_data_top = data;23 24	if (!io || !io->if_object || !data)25		return -EINVAL;26 27	if (sub_address + size > 0x100)28		return -EINVAL;29 30	spi = io->if_object;31 32	if (tgt == CXD2880_IO_TGT_SYS)33		send_data[0] = 0x0b;34	else35		send_data[0] = 0x0a;36 37	send_data[3] = 0;38	send_data[4] = 0;39	send_data[5] = 0;40 41	while (size > 0) {42		send_data[1] = sub_address;43		if (size > 255)44			send_data[2] = 255;45		else46			send_data[2] = size;47 48		ret =49		    spi->write_read(spi, send_data, sizeof(send_data),50				    read_data_top, send_data[2]);51		if (ret)52			return ret;53 54		sub_address += send_data[2];55		read_data_top += send_data[2];56		size -= send_data[2];57	}58 59	return ret;60}61 62static int cxd2880_io_spi_write_reg(struct cxd2880_io *io,63				    enum cxd2880_io_tgt tgt,64				    u8 sub_address,65				    const u8 *data, u32 size)66{67	int ret = 0;68	struct cxd2880_spi *spi = NULL;69	u8 send_data[BURST_WRITE_MAX + 4];70	const u8 *write_data_top = data;71 72	if (!io || !io->if_object || !data)73		return -EINVAL;74 75	if (size > BURST_WRITE_MAX)76		return -EINVAL;77 78	if (sub_address + size > 0x100)79		return -EINVAL;80 81	spi = io->if_object;82 83	if (tgt == CXD2880_IO_TGT_SYS)84		send_data[0] = 0x0f;85	else86		send_data[0] = 0x0e;87 88	while (size > 0) {89		send_data[1] = sub_address;90		if (size > 255)91			send_data[2] = 255;92		else93			send_data[2] = size;94 95		memcpy(&send_data[3], write_data_top, send_data[2]);96 97		if (tgt == CXD2880_IO_TGT_SYS) {98			send_data[3 + send_data[2]] = 0x00;99			ret = spi->write(spi, send_data, send_data[2] + 4);100		} else {101			ret = spi->write(spi, send_data, send_data[2] + 3);102		}103		if (ret)104			return ret;105 106		sub_address += send_data[2];107		write_data_top += send_data[2];108		size -= send_data[2];109	}110 111	return ret;112}113 114int cxd2880_io_spi_create(struct cxd2880_io *io,115			  struct cxd2880_spi *spi, u8 slave_select)116{117	if (!io || !spi)118		return -EINVAL;119 120	io->read_regs = cxd2880_io_spi_read_reg;121	io->write_regs = cxd2880_io_spi_write_reg;122	io->write_reg = cxd2880_io_common_write_one_reg;123	io->if_object = spi;124	io->i2c_address_sys = 0;125	io->i2c_address_demod = 0;126	io->slave_select = slave_select;127 128	return 0;129}130