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");