cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sigmadsp-i2c.c (2194B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Load Analog Devices SigmaStudio firmware files
      4 *
      5 * Copyright 2009-2011 Analog Devices Inc.
      6 */
      7
      8#include <linux/export.h>
      9#include <linux/i2c.h>
     10#include <linux/module.h>
     11#include <linux/slab.h>
     12#include <asm/unaligned.h>
     13
     14#include "sigmadsp.h"
     15
     16static int sigmadsp_write_i2c(void *control_data,
     17	unsigned int addr, const uint8_t data[], size_t len)
     18{
     19	uint8_t *buf;
     20	int ret;
     21
     22	buf = kzalloc(2 + len, GFP_KERNEL | GFP_DMA);
     23	if (!buf)
     24		return -ENOMEM;
     25
     26	put_unaligned_be16(addr, buf);
     27	memcpy(buf + 2, data, len);
     28
     29	ret = i2c_master_send(control_data, buf, len + 2);
     30
     31	kfree(buf);
     32
     33	if (ret < 0)
     34		return ret;
     35
     36	return 0;
     37}
     38
     39static int sigmadsp_read_i2c(void *control_data,
     40	unsigned int addr, uint8_t data[], size_t len)
     41{
     42	struct i2c_client *client = control_data;
     43	struct i2c_msg msgs[2];
     44	uint8_t buf[2];
     45	int ret;
     46
     47	put_unaligned_be16(addr, buf);
     48
     49	msgs[0].addr = client->addr;
     50	msgs[0].len = sizeof(buf);
     51	msgs[0].buf = buf;
     52	msgs[0].flags = 0;
     53
     54	msgs[1].addr = client->addr;
     55	msgs[1].len = len;
     56	msgs[1].buf = data;
     57	msgs[1].flags = I2C_M_RD;
     58
     59	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
     60	if (ret < 0)
     61		return ret;
     62	else if (ret != ARRAY_SIZE(msgs))
     63		return -EIO;
     64	return 0;
     65}
     66
     67/**
     68 * devm_sigmadsp_init_i2c() - Initialize SigmaDSP instance
     69 * @client: The parent I2C device
     70 * @ops: The sigmadsp_ops to use for this instance
     71 * @firmware_name: Name of the firmware file to load
     72 *
     73 * Allocates a SigmaDSP instance and loads the specified firmware file.
     74 *
     75 * Returns a pointer to a struct sigmadsp on success, or a PTR_ERR() on error.
     76 */
     77struct sigmadsp *devm_sigmadsp_init_i2c(struct i2c_client *client,
     78	const struct sigmadsp_ops *ops,	const char *firmware_name)
     79{
     80	struct sigmadsp *sigmadsp;
     81
     82	sigmadsp = devm_sigmadsp_init(&client->dev, ops, firmware_name);
     83	if (IS_ERR(sigmadsp))
     84		return sigmadsp;
     85
     86	sigmadsp->control_data = client;
     87	sigmadsp->write = sigmadsp_write_i2c;
     88	sigmadsp->read = sigmadsp_read_i2c;
     89
     90	return sigmadsp;
     91}
     92EXPORT_SYMBOL_GPL(devm_sigmadsp_init_i2c);
     93
     94MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
     95MODULE_DESCRIPTION("SigmaDSP I2C firmware loader");
     96MODULE_LICENSE("GPL");