linux/sound/soc/codecs/rl6347a.c
Thomas Gleixner d2912cb15b treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 500
Based on 2 normalized pattern(s):

  this program is free software you can redistribute it and or modify
  it under the terms of the gnu general public license version 2 as
  published by the free software foundation

  this program is free software you can redistribute it and or modify
  it under the terms of the gnu general public license version 2 as
  published by the free software foundation #

extracted by the scancode license scanner the SPDX license identifier

  GPL-2.0-only

has been chosen to replace the boilerplate/reference in 4122 file(s).

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Enrico Weigelt <info@metux.net>
Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org>
Reviewed-by: Allison Randal <allison@lohutok.net>
Cc: linux-spdx@vger.kernel.org
Link: https://lkml.kernel.org/r/20190604081206.933168790@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-06-19 17:09:55 +02:00

109 lines
2.3 KiB
C

// SPDX-License-Identifier: GPL-2.0-only
/*
* rl6347a.c - RL6347A class device shared support
*
* Copyright 2015 Realtek Semiconductor Corp.
*
* Author: Oder Chiou <oder_chiou@realtek.com>
*/
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include "rl6347a.h"
int rl6347a_hw_write(void *context, unsigned int reg, unsigned int value)
{
struct i2c_client *client = context;
struct rl6347a_priv *rl6347a = i2c_get_clientdata(client);
u8 data[4];
int ret, i;
/* handle index registers */
if (reg <= 0xff) {
rl6347a_hw_write(client, RL6347A_COEF_INDEX, reg);
for (i = 0; i < rl6347a->index_cache_size; i++) {
if (reg == rl6347a->index_cache[i].reg) {
rl6347a->index_cache[i].def = value;
break;
}
}
reg = RL6347A_PROC_COEF;
}
data[0] = (reg >> 24) & 0xff;
data[1] = (reg >> 16) & 0xff;
/*
* 4 bit VID: reg should be 0
* 12 bit VID: value should be 0
* So we use an OR operator to handle it rather than use if condition.
*/
data[2] = ((reg >> 8) & 0xff) | ((value >> 8) & 0xff);
data[3] = value & 0xff;
ret = i2c_master_send(client, data, 4);
if (ret == 4)
return 0;
else
dev_err(&client->dev, "I2C error %d\n", ret);
if (ret < 0)
return ret;
else
return -EIO;
}
EXPORT_SYMBOL_GPL(rl6347a_hw_write);
int rl6347a_hw_read(void *context, unsigned int reg, unsigned int *value)
{
struct i2c_client *client = context;
struct i2c_msg xfer[2];
int ret;
__be32 be_reg, buf = 0x0;
unsigned int index, vid;
/* handle index registers */
if (reg <= 0xff) {
rl6347a_hw_write(client, RL6347A_COEF_INDEX, reg);
reg = RL6347A_PROC_COEF;
}
reg = reg | 0x80000;
vid = (reg >> 8) & 0xfff;
if (AC_VERB_GET_AMP_GAIN_MUTE == (vid & 0xf00)) {
index = (reg >> 8) & 0xf;
reg = (reg & ~0xf0f) | index;
}
be_reg = cpu_to_be32(reg);
/* Write register */
xfer[0].addr = client->addr;
xfer[0].flags = 0;
xfer[0].len = 4;
xfer[0].buf = (u8 *)&be_reg;
/* Read data */
xfer[1].addr = client->addr;
xfer[1].flags = I2C_M_RD;
xfer[1].len = 4;
xfer[1].buf = (u8 *)&buf;
ret = i2c_transfer(client->adapter, xfer, 2);
if (ret < 0)
return ret;
else if (ret != 2)
return -EIO;
*value = be32_to_cpu(buf);
return 0;
}
EXPORT_SYMBOL_GPL(rl6347a_hw_read);
MODULE_DESCRIPTION("RL6347A class device shared support");
MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>");
MODULE_LICENSE("GPL v2");