18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * cxd2880_tnrdmd_mon.c
48c2ecf20Sopenharmony_ci * Sony CXD2880 DVB-T2/T tuner + demodulator driver
58c2ecf20Sopenharmony_ci * common monitor functions
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include "cxd2880_common.h"
118c2ecf20Sopenharmony_ci#include "cxd2880_tnrdmd_mon.h"
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_cistatic const u8 rf_lvl_seq[2] = {
148c2ecf20Sopenharmony_ci	0x80, 0x00,
158c2ecf20Sopenharmony_ci};
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ciint cxd2880_tnrdmd_mon_rf_lvl(struct cxd2880_tnrdmd *tnr_dmd,
188c2ecf20Sopenharmony_ci			      int *rf_lvl_db)
198c2ecf20Sopenharmony_ci{
208c2ecf20Sopenharmony_ci	u8 rdata[2];
218c2ecf20Sopenharmony_ci	int ret;
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci	if (!tnr_dmd || !rf_lvl_db)
248c2ecf20Sopenharmony_ci		return -EINVAL;
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
278c2ecf20Sopenharmony_ci		return -EINVAL;
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
308c2ecf20Sopenharmony_ci				     CXD2880_IO_TGT_DMD,
318c2ecf20Sopenharmony_ci				     0x00, 0x00);
328c2ecf20Sopenharmony_ci	if (ret)
338c2ecf20Sopenharmony_ci		return ret;
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
368c2ecf20Sopenharmony_ci				     CXD2880_IO_TGT_DMD,
378c2ecf20Sopenharmony_ci				     0x10, 0x01);
388c2ecf20Sopenharmony_ci	if (ret)
398c2ecf20Sopenharmony_ci		return ret;
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
428c2ecf20Sopenharmony_ci				     CXD2880_IO_TGT_SYS,
438c2ecf20Sopenharmony_ci				     0x00, 0x10);
448c2ecf20Sopenharmony_ci	if (ret)
458c2ecf20Sopenharmony_ci		return ret;
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
488c2ecf20Sopenharmony_ci				      CXD2880_IO_TGT_SYS,
498c2ecf20Sopenharmony_ci				      0x5b, rf_lvl_seq, 2);
508c2ecf20Sopenharmony_ci	if (ret)
518c2ecf20Sopenharmony_ci		return ret;
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci	usleep_range(2000, 3000);
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
568c2ecf20Sopenharmony_ci				     CXD2880_IO_TGT_SYS,
578c2ecf20Sopenharmony_ci				     0x00, 0x1a);
588c2ecf20Sopenharmony_ci	if (ret)
598c2ecf20Sopenharmony_ci		return ret;
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci	ret = tnr_dmd->io->read_regs(tnr_dmd->io,
628c2ecf20Sopenharmony_ci				     CXD2880_IO_TGT_SYS,
638c2ecf20Sopenharmony_ci				     0x15, rdata, 2);
648c2ecf20Sopenharmony_ci	if (ret)
658c2ecf20Sopenharmony_ci		return ret;
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci	if (rdata[0] || rdata[1])
688c2ecf20Sopenharmony_ci		return -EINVAL;
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci	ret = tnr_dmd->io->read_regs(tnr_dmd->io,
718c2ecf20Sopenharmony_ci				     CXD2880_IO_TGT_SYS,
728c2ecf20Sopenharmony_ci				     0x11, rdata, 2);
738c2ecf20Sopenharmony_ci	if (ret)
748c2ecf20Sopenharmony_ci		return ret;
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci	*rf_lvl_db =
778c2ecf20Sopenharmony_ci	    cxd2880_convert2s_complement((rdata[0] << 3) |
788c2ecf20Sopenharmony_ci					 ((rdata[1] & 0xe0) >> 5), 11);
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci	*rf_lvl_db *= 125;
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
838c2ecf20Sopenharmony_ci				     CXD2880_IO_TGT_DMD,
848c2ecf20Sopenharmony_ci				     0x00, 0x00);
858c2ecf20Sopenharmony_ci	if (ret)
868c2ecf20Sopenharmony_ci		return ret;
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
898c2ecf20Sopenharmony_ci				     CXD2880_IO_TGT_DMD,
908c2ecf20Sopenharmony_ci				     0x10, 0x00);
918c2ecf20Sopenharmony_ci	if (ret)
928c2ecf20Sopenharmony_ci		return ret;
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci	if (tnr_dmd->rf_lvl_cmpstn)
958c2ecf20Sopenharmony_ci		ret = tnr_dmd->rf_lvl_cmpstn(tnr_dmd, rf_lvl_db);
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci	return ret;
988c2ecf20Sopenharmony_ci}
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ciint cxd2880_tnrdmd_mon_rf_lvl_sub(struct cxd2880_tnrdmd *tnr_dmd,
1018c2ecf20Sopenharmony_ci				  int *rf_lvl_db)
1028c2ecf20Sopenharmony_ci{
1038c2ecf20Sopenharmony_ci	if (!tnr_dmd || !rf_lvl_db)
1048c2ecf20Sopenharmony_ci		return -EINVAL;
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ci	if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
1078c2ecf20Sopenharmony_ci		return -EINVAL;
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci	return cxd2880_tnrdmd_mon_rf_lvl(tnr_dmd->diver_sub, rf_lvl_db);
1108c2ecf20Sopenharmony_ci}
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ciint cxd2880_tnrdmd_mon_internal_cpu_status(struct cxd2880_tnrdmd
1138c2ecf20Sopenharmony_ci					   *tnr_dmd, u16 *status)
1148c2ecf20Sopenharmony_ci{
1158c2ecf20Sopenharmony_ci	u8 data[2] = { 0 };
1168c2ecf20Sopenharmony_ci	int ret;
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ci	if (!tnr_dmd || !status)
1198c2ecf20Sopenharmony_ci		return -EINVAL;
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_ci	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
1228c2ecf20Sopenharmony_ci				     CXD2880_IO_TGT_SYS,
1238c2ecf20Sopenharmony_ci				     0x00, 0x1a);
1248c2ecf20Sopenharmony_ci	if (ret)
1258c2ecf20Sopenharmony_ci		return ret;
1268c2ecf20Sopenharmony_ci	ret = tnr_dmd->io->read_regs(tnr_dmd->io,
1278c2ecf20Sopenharmony_ci				     CXD2880_IO_TGT_SYS,
1288c2ecf20Sopenharmony_ci				     0x15, data, 2);
1298c2ecf20Sopenharmony_ci	if (ret)
1308c2ecf20Sopenharmony_ci		return ret;
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_ci	*status = (data[0] << 8) | data[1];
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci	return 0;
1358c2ecf20Sopenharmony_ci}
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ciint cxd2880_tnrdmd_mon_internal_cpu_status_sub(struct
1388c2ecf20Sopenharmony_ci					       cxd2880_tnrdmd
1398c2ecf20Sopenharmony_ci					       *tnr_dmd,
1408c2ecf20Sopenharmony_ci					       u16 *status)
1418c2ecf20Sopenharmony_ci{
1428c2ecf20Sopenharmony_ci	if (!tnr_dmd || !status)
1438c2ecf20Sopenharmony_ci		return -EINVAL;
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci	if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
1468c2ecf20Sopenharmony_ci		return -EINVAL;
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_ci	return cxd2880_tnrdmd_mon_internal_cpu_status(tnr_dmd->diver_sub,
1498c2ecf20Sopenharmony_ci						      status);
1508c2ecf20Sopenharmony_ci}
151