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

adt7316-spi.c (3504B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * API bus driver for ADT7316/7/8 ADT7516/7/9 digital temperature
      4 * sensor, ADC and DAC
      5 *
      6 * Copyright 2010 Analog Devices Inc.
      7 */
      8
      9#include <linux/device.h>
     10#include <linux/kernel.h>
     11#include <linux/module.h>
     12#include <linux/interrupt.h>
     13#include <linux/spi/spi.h>
     14
     15#include "adt7316.h"
     16
     17#define ADT7316_SPI_MAX_FREQ_HZ		5000000
     18#define ADT7316_SPI_CMD_READ		0x91
     19#define ADT7316_SPI_CMD_WRITE		0x90
     20
     21/*
     22 * adt7316 register access by SPI
     23 */
     24
     25static int adt7316_spi_multi_read(void *client, u8 reg, u8 count, u8 *data)
     26{
     27	struct spi_device *spi_dev = client;
     28	u8 cmd[2];
     29	int ret;
     30
     31	if (count > ADT7316_REG_MAX_ADDR)
     32		count = ADT7316_REG_MAX_ADDR;
     33
     34	cmd[0] = ADT7316_SPI_CMD_WRITE;
     35	cmd[1] = reg;
     36
     37	ret = spi_write(spi_dev, cmd, 2);
     38	if (ret < 0) {
     39		dev_err(&spi_dev->dev, "SPI fail to select reg\n");
     40		return ret;
     41	}
     42
     43	cmd[0] = ADT7316_SPI_CMD_READ;
     44
     45	ret = spi_write_then_read(spi_dev, cmd, 1, data, count);
     46	if (ret < 0) {
     47		dev_err(&spi_dev->dev, "SPI read data error\n");
     48		return ret;
     49	}
     50
     51	return 0;
     52}
     53
     54static int adt7316_spi_multi_write(void *client, u8 reg, u8 count, u8 *data)
     55{
     56	struct spi_device *spi_dev = client;
     57	u8 buf[ADT7316_REG_MAX_ADDR + 2];
     58	int i, ret;
     59
     60	if (count > ADT7316_REG_MAX_ADDR)
     61		count = ADT7316_REG_MAX_ADDR;
     62
     63	buf[0] = ADT7316_SPI_CMD_WRITE;
     64	buf[1] = reg;
     65	for (i = 0; i < count; i++)
     66		buf[i + 2] = data[i];
     67
     68	ret = spi_write(spi_dev, buf, count + 2);
     69	if (ret < 0) {
     70		dev_err(&spi_dev->dev, "SPI write error\n");
     71		return ret;
     72	}
     73
     74	return ret;
     75}
     76
     77static int adt7316_spi_read(void *client, u8 reg, u8 *data)
     78{
     79	return adt7316_spi_multi_read(client, reg, 1, data);
     80}
     81
     82static int adt7316_spi_write(void *client, u8 reg, u8 val)
     83{
     84	return adt7316_spi_multi_write(client, reg, 1, &val);
     85}
     86
     87/*
     88 * device probe and remove
     89 */
     90
     91static int adt7316_spi_probe(struct spi_device *spi_dev)
     92{
     93	struct adt7316_bus bus = {
     94		.client = spi_dev,
     95		.irq = spi_dev->irq,
     96		.read = adt7316_spi_read,
     97		.write = adt7316_spi_write,
     98		.multi_read = adt7316_spi_multi_read,
     99		.multi_write = adt7316_spi_multi_write,
    100	};
    101
    102	/* don't exceed max specified SPI CLK frequency */
    103	if (spi_dev->max_speed_hz > ADT7316_SPI_MAX_FREQ_HZ) {
    104		dev_err(&spi_dev->dev, "SPI CLK %d Hz?\n",
    105			spi_dev->max_speed_hz);
    106		return -EINVAL;
    107	}
    108
    109	/* switch from default I2C protocol to SPI protocol */
    110	adt7316_spi_write(spi_dev, 0, 0);
    111	adt7316_spi_write(spi_dev, 0, 0);
    112	adt7316_spi_write(spi_dev, 0, 0);
    113
    114	return adt7316_probe(&spi_dev->dev, &bus, spi_dev->modalias);
    115}
    116
    117static const struct spi_device_id adt7316_spi_id[] = {
    118	{ "adt7316", 0 },
    119	{ "adt7317", 0 },
    120	{ "adt7318", 0 },
    121	{ "adt7516", 0 },
    122	{ "adt7517", 0 },
    123	{ "adt7519", 0 },
    124	{ }
    125};
    126
    127MODULE_DEVICE_TABLE(spi, adt7316_spi_id);
    128
    129static const struct of_device_id adt7316_of_spi_match[] = {
    130	{ .compatible = "adi,adt7316" },
    131	{ .compatible = "adi,adt7317" },
    132	{ .compatible = "adi,adt7318" },
    133	{ .compatible = "adi,adt7516" },
    134	{ .compatible = "adi,adt7517" },
    135	{ .compatible = "adi,adt7519" },
    136	{ }
    137};
    138
    139MODULE_DEVICE_TABLE(of, adt7316_of_spi_match);
    140
    141static struct spi_driver adt7316_driver = {
    142	.driver = {
    143		.name = "adt7316",
    144		.of_match_table = adt7316_of_spi_match,
    145		.pm = ADT7316_PM_OPS,
    146	},
    147	.probe = adt7316_spi_probe,
    148	.id_table = adt7316_spi_id,
    149};
    150module_spi_driver(adt7316_driver);
    151
    152MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
    153MODULE_DESCRIPTION("SPI bus driver for Analog Devices ADT7316/7/8 and ADT7516/7/9 digital temperature sensor, ADC and DAC");
    154MODULE_LICENSE("GPL v2");