rsmu_spi.c (6562B)
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * SPI driver for Renesas Synchronization Management Unit (SMU) devices. 4 * 5 * Copyright (C) 2021 Integrated Device Technology, Inc., a Renesas Company. 6 */ 7 8#include <linux/init.h> 9#include <linux/kernel.h> 10#include <linux/mfd/core.h> 11#include <linux/mfd/rsmu.h> 12#include <linux/module.h> 13#include <linux/of.h> 14#include <linux/regmap.h> 15#include <linux/slab.h> 16#include <linux/spi/spi.h> 17 18#include "rsmu.h" 19 20#define RSMU_CM_PAGE_ADDR 0x7C 21#define RSMU_SABRE_PAGE_ADDR 0x7F 22#define RSMU_HIGHER_ADDR_MASK 0xFF80 23#define RSMU_HIGHER_ADDR_SHIFT 7 24#define RSMU_LOWER_ADDR_MASK 0x7F 25 26static int rsmu_read_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u16 bytes) 27{ 28 struct spi_device *client = to_spi_device(rsmu->dev); 29 struct spi_transfer xfer = {0}; 30 struct spi_message msg; 31 u8 cmd[256] = {0}; 32 u8 rsp[256] = {0}; 33 int ret; 34 35 cmd[0] = reg | 0x80; 36 xfer.rx_buf = rsp; 37 xfer.len = bytes + 1; 38 xfer.tx_buf = cmd; 39 xfer.bits_per_word = client->bits_per_word; 40 xfer.speed_hz = client->max_speed_hz; 41 42 spi_message_init(&msg); 43 spi_message_add_tail(&xfer, &msg); 44 45 /* 46 * 4-wire SPI is a shift register, so for every byte you send, 47 * you get one back at the same time. Example read from 0xC024, 48 * which has value of 0x2D 49 * 50 * MOSI: 51 * 7C 00 C0 #Set page register 52 * A4 00 #MSB is set, so this is read command 53 * MISO: 54 * XX 2D #XX is a dummy byte from sending A4 and we 55 * need to throw it away 56 */ 57 ret = spi_sync(client, &msg); 58 if (ret >= 0) 59 memcpy(buf, &rsp[1], xfer.len-1); 60 61 return ret; 62} 63 64static int rsmu_write_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u16 bytes) 65{ 66 struct spi_device *client = to_spi_device(rsmu->dev); 67 struct spi_transfer xfer = {0}; 68 struct spi_message msg; 69 u8 cmd[256] = {0}; 70 71 cmd[0] = reg; 72 memcpy(&cmd[1], buf, bytes); 73 74 xfer.len = bytes + 1; 75 xfer.tx_buf = cmd; 76 xfer.bits_per_word = client->bits_per_word; 77 xfer.speed_hz = client->max_speed_hz; 78 spi_message_init(&msg); 79 spi_message_add_tail(&xfer, &msg); 80 81 return spi_sync(client, &msg); 82} 83 84/* 85 * 1-byte (1B) offset addressing: 86 * 16-bit register address: the lower 7 bits of the register address come 87 * from the offset addr byte and the upper 9 bits come from the page register. 88 */ 89static int rsmu_write_page_register(struct rsmu_ddata *rsmu, u16 reg) 90{ 91 u8 page_reg; 92 u8 buf[2]; 93 u16 bytes; 94 u16 page; 95 int err; 96 97 switch (rsmu->type) { 98 case RSMU_CM: 99 page_reg = RSMU_CM_PAGE_ADDR; 100 page = reg & RSMU_HIGHER_ADDR_MASK; 101 buf[0] = (u8)(page & 0xff); 102 buf[1] = (u8)((page >> 8) & 0xff); 103 bytes = 2; 104 break; 105 case RSMU_SABRE: 106 page_reg = RSMU_SABRE_PAGE_ADDR; 107 page = reg >> RSMU_HIGHER_ADDR_SHIFT; 108 buf[0] = (u8)(page & 0xff); 109 bytes = 1; 110 break; 111 default: 112 dev_err(rsmu->dev, "Unsupported RSMU device type: %d\n", rsmu->type); 113 return -ENODEV; 114 } 115 116 /* Simply return if we are on the same page */ 117 if (rsmu->page == page) 118 return 0; 119 120 err = rsmu_write_device(rsmu, page_reg, buf, bytes); 121 if (err) 122 dev_err(rsmu->dev, "Failed to set page offset 0x%x\n", page); 123 else 124 /* Remember the last page */ 125 rsmu->page = page; 126 127 return err; 128} 129 130static int rsmu_reg_read(void *context, unsigned int reg, unsigned int *val) 131{ 132 struct rsmu_ddata *rsmu = spi_get_drvdata((struct spi_device *)context); 133 u8 addr = (u8)(reg & RSMU_LOWER_ADDR_MASK); 134 int err; 135 136 err = rsmu_write_page_register(rsmu, reg); 137 if (err) 138 return err; 139 140 err = rsmu_read_device(rsmu, addr, (u8 *)val, 1); 141 if (err) 142 dev_err(rsmu->dev, "Failed to read offset address 0x%x\n", addr); 143 144 return err; 145} 146 147static int rsmu_reg_write(void *context, unsigned int reg, unsigned int val) 148{ 149 struct rsmu_ddata *rsmu = spi_get_drvdata((struct spi_device *)context); 150 u8 addr = (u8)(reg & RSMU_LOWER_ADDR_MASK); 151 u8 data = (u8)val; 152 int err; 153 154 err = rsmu_write_page_register(rsmu, reg); 155 if (err) 156 return err; 157 158 err = rsmu_write_device(rsmu, addr, &data, 1); 159 if (err) 160 dev_err(rsmu->dev, 161 "Failed to write offset address 0x%x\n", addr); 162 163 return err; 164} 165 166static const struct regmap_config rsmu_cm_regmap_config = { 167 .reg_bits = 16, 168 .val_bits = 8, 169 .max_register = 0xD000, 170 .reg_read = rsmu_reg_read, 171 .reg_write = rsmu_reg_write, 172 .cache_type = REGCACHE_NONE, 173}; 174 175static const struct regmap_config rsmu_sabre_regmap_config = { 176 .reg_bits = 16, 177 .val_bits = 8, 178 .max_register = 0x400, 179 .reg_read = rsmu_reg_read, 180 .reg_write = rsmu_reg_write, 181 .cache_type = REGCACHE_NONE, 182}; 183 184static int rsmu_spi_probe(struct spi_device *client) 185{ 186 const struct spi_device_id *id = spi_get_device_id(client); 187 const struct regmap_config *cfg; 188 struct rsmu_ddata *rsmu; 189 int ret; 190 191 rsmu = devm_kzalloc(&client->dev, sizeof(*rsmu), GFP_KERNEL); 192 if (!rsmu) 193 return -ENOMEM; 194 195 spi_set_drvdata(client, rsmu); 196 197 rsmu->dev = &client->dev; 198 rsmu->type = (enum rsmu_type)id->driver_data; 199 200 /* Initialize regmap */ 201 switch (rsmu->type) { 202 case RSMU_CM: 203 cfg = &rsmu_cm_regmap_config; 204 break; 205 case RSMU_SABRE: 206 cfg = &rsmu_sabre_regmap_config; 207 break; 208 default: 209 dev_err(rsmu->dev, "Unsupported RSMU device type: %d\n", rsmu->type); 210 return -ENODEV; 211 } 212 213 rsmu->regmap = devm_regmap_init(&client->dev, NULL, client, cfg); 214 if (IS_ERR(rsmu->regmap)) { 215 ret = PTR_ERR(rsmu->regmap); 216 dev_err(rsmu->dev, "Failed to allocate register map: %d\n", ret); 217 return ret; 218 } 219 220 return rsmu_core_init(rsmu); 221} 222 223static void rsmu_spi_remove(struct spi_device *client) 224{ 225 struct rsmu_ddata *rsmu = spi_get_drvdata(client); 226 227 rsmu_core_exit(rsmu); 228} 229 230static const struct spi_device_id rsmu_spi_id[] = { 231 { "8a34000", RSMU_CM }, 232 { "8a34001", RSMU_CM }, 233 { "82p33810", RSMU_SABRE }, 234 { "82p33811", RSMU_SABRE }, 235 {} 236}; 237MODULE_DEVICE_TABLE(spi, rsmu_spi_id); 238 239static const struct of_device_id rsmu_spi_of_match[] = { 240 { .compatible = "idt,8a34000", .data = (void *)RSMU_CM }, 241 { .compatible = "idt,8a34001", .data = (void *)RSMU_CM }, 242 { .compatible = "idt,82p33810", .data = (void *)RSMU_SABRE }, 243 { .compatible = "idt,82p33811", .data = (void *)RSMU_SABRE }, 244 {} 245}; 246MODULE_DEVICE_TABLE(of, rsmu_spi_of_match); 247 248static struct spi_driver rsmu_spi_driver = { 249 .driver = { 250 .name = "rsmu-spi", 251 .of_match_table = of_match_ptr(rsmu_spi_of_match), 252 }, 253 .probe = rsmu_spi_probe, 254 .remove = rsmu_spi_remove, 255 .id_table = rsmu_spi_id, 256}; 257 258static int __init rsmu_spi_init(void) 259{ 260 return spi_register_driver(&rsmu_spi_driver); 261} 262subsys_initcall(rsmu_spi_init); 263 264static void __exit rsmu_spi_exit(void) 265{ 266 spi_unregister_driver(&rsmu_spi_driver); 267} 268module_exit(rsmu_spi_exit); 269 270MODULE_DESCRIPTION("Renesas SMU SPI driver"); 271MODULE_LICENSE("GPL");