<commit_before>/*
 * soc-cache.c  --  ASoC register cache helpers
 *
 * Copyright 2009 Wolfson Microelectronics PLC.
 *
 * Author: <NAME> <<EMAIL>>
 *
 *  This program is free software; you can redistribute  it and/or modify it
 *  under  the terms of  the GNU General  Public License as published by the
 *  Free Software Foundation;  either version 2 of the  License, or (at your
 *  option) any later version.
 */

#include <linux/i2c.h>
#include <linux/spi/spi.h>
#include <sound/soc.h>
#include <linux/lzo.h>
#include <linux/bitmap.h>
#include <linux/rbtree.h>

#include <trace/events/asoc.h>

#if defined(CONFIG_SPI_MASTER)
static int do_spi_write(void *control_data, const void *msg,
			int len)
{
	struct spi_device *spi = control_data;
	struct spi_transfer t;
	struct spi_message m;

	if (len <= 0)
		return 0;

	spi_message_init(&m);
	memset(&t, 0, sizeof t);

	t.tx_buf = msg;
	t.len = len;

	spi_message_add_tail(&t, &m);
	spi_sync(spi, &m);

	return len;
}
#endif

static int do_hw_write(struct snd_soc_codec *codec, unsigned int reg,
		       unsigned int value, const void *data, int len)
{
	int ret;

	if (!snd_soc_codec_volatile_register(codec, reg) &&
	    reg < codec->driver->reg_cache_size &&
	    !codec->cache_bypass) {
		ret = snd_soc_cache_write(codec, reg, value);
		if (ret < 0)
			return -1;
	}

	if (codec->cache_only) {
		codec->cache_sync = 1;
		return 0;
	}

	ret = codec->hw_write(codec->control_data, data, len);
	if (ret == len)
		return 0;
	if (ret < 0)
		return ret;
	else
		return -EIO;
}

static unsigned int do_hw_read(struct snd_soc_codec *codec, unsigned int reg)
{
	int ret;
	unsigned int val;

	if (reg >= codec->driver->reg_cache_size ||
	    snd_soc_codec_volatile_register(codec, reg) ||
	    codec->cache_bypass) {
		if (codec->cache_only)
			return -1;

		BUG_ON(!codec->hw_read);
		return codec->hw_read(codec, reg);
	}

	ret = snd_soc_cache_read(codec, reg, &val);
	if (ret < 0)
		return -1;
	return val;
}

static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec,
				      unsigned int reg)
{
	return do_hw_read(codec, reg);
}

static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
			      unsigned int value)
{
	u8 data[2];

	data[0] = (reg << 4) | ((value >> 8) & 0x000f);
	data[1] = value & 0x00ff;

	return do_hw_write(codec, reg, value, data, 2);
}

#if defined(CONFIG_SPI_MASTER)
static int snd_soc_4_12_spi_write(void *control_data, const char *data,
				  int len)
{
	u8 msg[2];

	msg[0] = data[1];
	msg[1] = data[0];

	return do_spi_write(control_data, msg, len);
}
#else
#define snd_soc_4_12_spi_write NULL
#endif

static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
				     unsigned int reg)
{
	return do_hw_read(codec, reg);
}

static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
			     unsigned int value)
{
	u16 data;

	data = cpu_to_be16((reg << 9) | (value & 0x1ff));

	return do_hw_write(codec, reg, value, &data, 2);
}

#if defined(CONFIG_SPI_MASTER)
static int snd_soc_7_9_spi_write(void *control_data, const char *data,
				 int len)
{
	u8 msg[2];

	msg[0] = data[0];
	msg[1] = data[1];

	return do_spi_write(control_data, msg, len);
}
#else
#define snd_soc_7_9_spi_write NULL
#endif

static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
			     unsigned int value)
{
	u8 data[2];

	reg &= 0xff;
	data[0] = reg;
	data[1] = value & 0xff;

	return do_hw_write(codec, reg, value, data, 2);
}

static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
				     unsigned int reg)
{
	return do_hw_read(codec, reg);
}

#if defined(CONFIG_SPI_MASTER)
static int snd_soc_8_8_spi_write(void *control_data, const char *data,
				 int len)
{
	u8 msg[2];

	msg[0] = data[0];
	msg[1] = data[1];

	return do_spi_write(control_data, msg, len);
}
#else
#define snd_soc_8_8_spi_write NULL
#endif

static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
			      unsigned int value)
{
	u8 data[3];

	data[0] = reg;
	data[1] = (value >> 8) & 0xff;
	data[2] = value & 0xff;

	return do_hw_write(codec, reg, value, data, 3);
}

static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
				      unsigned int reg)
{
	return do_hw_read(codec, reg);
}

#if defined(CONFIG_SPI_MASTER)
static int snd_soc_8_16_spi_write(void *control_data, const char *data,
				  int len)
{
	u8 msg[3];

	msg[0] = data[0];
	msg[1] = data[1];
	msg[2] = data[2];

	return do_spi_write(control_data, msg, len);
}
#else
#define snd_soc_8_16_spi_write NULL
#endif

#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
static unsigned int do_i2c_read(struct snd_soc_codec *codec,
				void *reg, int reglen,<commit_msg>ASoC: Use cpu_to_be16() in 8x16 write<commit_after>/*
 * soc-cache.c  --  ASoC register cache helpers
 *
 * Copyright 2009 Wolfson Microelectronics PLC.
 *
 * Author: <NAME> <<EMAIL>>
 *
 *  This program is free software; you can redistribute  it and/or modify it
 *  under  the terms of  the GNU General  Public License as published by the
 *  Free Software Foundation;  either version 2 of the  License, or (at your
 *  option) any later version.
 */

#include <linux/i2c.h>
#include <linux/spi/spi.h>
#include <sound/soc.h>
#include <linux/lzo.h>
#include <linux/bitmap.h>
#include <linux/rbtree.h>

#include <trace/events/asoc.h>

#if defined(CONFIG_SPI_MASTER)
static int do_spi_write(void *control_data, const void *msg,
			int len)
{
	struct spi_device *spi = control_data;
	struct spi_transfer t;
	struct spi_message m;

	if (len <= 0)
		return 0;

	spi_message_init(&m);
	memset(&t, 0, sizeof t);

	t.tx_buf = msg;
	t.len = len;

	spi_message_add_tail(&t, &m);
	spi_sync(spi, &m);

	return len;
}
#endif

static int do_hw_write(struct snd_soc_codec *codec, unsigned int reg,
		       unsigned int value, const void *data, int len)
{
	int ret;

	if (!snd_soc_codec_volatile_register(codec, reg) &&
	    reg < codec->driver->reg_cache_size &&
	    !codec->cache_bypass) {
		ret = snd_soc_cache_write(codec, reg, value);
		if (ret < 0)
			return -1;
	}

	if (codec->cache_only) {
		codec->cache_sync = 1;
		return 0;
	}

	ret = codec->hw_write(codec->control_data, data, len);
	if (ret == len)
		return 0;
	if (ret < 0)
		return ret;
	else
		return -EIO;
}

static unsigned int do_hw_read(struct snd_soc_codec *codec, unsigned int reg)
{
	int ret;
	unsigned int val;

	if (reg >= codec->driver->reg_cache_size ||
	    snd_soc_codec_volatile_register(codec, reg) ||
	    codec->cache_bypass) {
		if (codec->cache_only)
			return -1;

		BUG_ON(!codec->hw_read);
		return codec->hw_read(codec, reg);
	}

	ret = snd_soc_cache_read(codec, reg, &val);
	if (ret < 0)
		return -1;
	return val;
}

static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec,
				      unsigned int reg)
{
	return do_hw_read(codec, reg);
}

static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
			      unsigned int value)
{
	u8 data[2];

	data[0] = (reg << 4) | ((value >> 8) & 0x000f);
	data[1] = value & 0x00ff;

	return do_hw_write(codec, reg, value, data, 2);
}

#if defined(CONFIG_SPI_MASTER)
static int snd_soc_4_12_spi_write(void *control_data, const char *data,
				  int len)
{
	u8 msg[2];

	msg[0] = data[1];
	msg[1] = data[0];

	return do_spi_write(control_data, msg, len);
}
#else
#define snd_soc_4_12_spi_write NULL
#endif

static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
				     unsigned int reg)
{
	return do_hw_read(codec, reg);
}

static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
			     unsigned int value)
{
	u16 data;

	data = cpu_to_be16((reg << 9) | (value & 0x1ff));

	return do_hw_write(codec, reg, value, &data, 2);
}

#if defined(CONFIG_SPI_MASTER)
static int snd_soc_7_9_spi_write(void *control_data, const char *data,
				 int len)
{
	u8 msg[2];

	msg[0] = data[0];
	msg[1] = data[1];

	return do_spi_write(control_data, msg, len);
}
#else
#define snd_soc_7_9_spi_write NULL
#endif

static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
			     unsigned int value)
{
	u8 data[2];

	reg &= 0xff;
	data[0] = reg;
	data[1] = value & 0xff;

	return do_hw_write(codec, reg, value, data, 2);
}

static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
				     unsigned int reg)
{
	return do_hw_read(codec, reg);
}

#if defined(CONFIG_SPI_MASTER)
static int snd_soc_8_8_spi_write(void *control_data, const char *data,
				 int len)
{
	u8 msg[2];

	msg[0] = data[0];
	msg[1] = data[1];

	return do_spi_write(control_data, msg, len);
}
#else
#define snd_soc_8_8_spi_write NULL
#endif

static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
			      unsigned int value)
{
	u8 data[3];
	u16 val = cpu_to_be16(value);

	data[0] = reg;
	memcpy(&data[1], &val, sizeof(val));

	return do_hw_write(codec, reg, value, data, 3);
}

static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
				      unsigned int reg)
{
	return do_hw_read(codec, reg);
}

#if defined(CONFIG_SPI_MASTER)
static int snd_soc_8_16_spi_write(void *control_data, const char *data,
				  int len)
{
	u8 msg[3];

	msg[0] = data[0];
	msg[1] = data[1];
	msg[2] = data[2];

	return do_spi_write(control_data, msg, len);
}
#else
#define snd_soc_8_16_spi_write NULL
#endif

#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
static unsigned int do_i2c_read(struct snd_soc_codec *codec,
				void *reg, int reglen,
{'fraction_non_alphanumeric': 0.12462908011869436, 'fraction_numerical': 0.02702416278083934, 'mean_word_length': 4.159650082012028, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2186992', 'n_tokens_mistral': 4003, 'n_tokens_neox': 3706, 'n_words': 963}