brintos

brintos / linux-shallow public Read only

0
0
Text · 2.3 KiB · fa8ac34 Raw
109 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * rl6347a.c - RL6347A class device shared support4 *5 * Copyright 2015 Realtek Semiconductor Corp.6 *7 * Author: Oder Chiou <oder_chiou@realtek.com>8 */9 10#include <linux/module.h>11#include <linux/i2c.h>12#include <linux/regmap.h>13 14#include "rl6347a.h"15 16int rl6347a_hw_write(void *context, unsigned int reg, unsigned int value)17{18	struct i2c_client *client = context;19	struct rl6347a_priv *rl6347a = i2c_get_clientdata(client);20	u8 data[4];21	int ret, i;22 23	/* handle index registers */24	if (reg <= 0xff) {25		rl6347a_hw_write(client, RL6347A_COEF_INDEX, reg);26		for (i = 0; i < rl6347a->index_cache_size; i++) {27			if (reg == rl6347a->index_cache[i].reg) {28				rl6347a->index_cache[i].def = value;29				break;30			}31 32		}33		reg = RL6347A_PROC_COEF;34	}35 36	data[0] = (reg >> 24) & 0xff;37	data[1] = (reg >> 16) & 0xff;38	/*39	 * 4 bit VID: reg should be 040	 * 12 bit VID: value should be 041	 * So we use an OR operator to handle it rather than use if condition.42	 */43	data[2] = ((reg >> 8) & 0xff) | ((value >> 8) & 0xff);44	data[3] = value & 0xff;45 46	ret = i2c_master_send(client, data, 4);47 48	if (ret == 4)49		return 0;50	else51		dev_err(&client->dev, "I2C error %d\n", ret);52	if (ret < 0)53		return ret;54	else55		return -EIO;56}57EXPORT_SYMBOL_GPL(rl6347a_hw_write);58 59int rl6347a_hw_read(void *context, unsigned int reg, unsigned int *value)60{61	struct i2c_client *client = context;62	struct i2c_msg xfer[2];63	int ret;64	__be32 be_reg, buf = 0x0;65	unsigned int index, vid;66 67	/* handle index registers */68	if (reg <= 0xff) {69		rl6347a_hw_write(client, RL6347A_COEF_INDEX, reg);70		reg = RL6347A_PROC_COEF;71	}72 73	reg = reg | 0x80000;74	vid = (reg >> 8) & 0xfff;75 76	if (AC_VERB_GET_AMP_GAIN_MUTE == (vid & 0xf00)) {77		index = (reg >> 8) & 0xf;78		reg = (reg & ~0xf0f) | index;79	}80	be_reg = cpu_to_be32(reg);81 82	/* Write register */83	xfer[0].addr = client->addr;84	xfer[0].flags = 0;85	xfer[0].len = 4;86	xfer[0].buf = (u8 *)&be_reg;87 88	/* Read data */89	xfer[1].addr = client->addr;90	xfer[1].flags = I2C_M_RD;91	xfer[1].len = 4;92	xfer[1].buf = (u8 *)&buf;93 94	ret = i2c_transfer(client->adapter, xfer, 2);95	if (ret < 0)96		return ret;97	else if (ret != 2)98		return -EIO;99 100	*value = be32_to_cpu(buf);101 102	return 0;103}104EXPORT_SYMBOL_GPL(rl6347a_hw_read);105 106MODULE_DESCRIPTION("RL6347A class device shared support");107MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>");108MODULE_LICENSE("GPL v2");109