1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Intel La Jolla Cove Adapter USB-SPI driver 4 * 5 * Copyright (c) 2023, Intel Corporation. 6 */ 7 8 #include <linux/auxiliary_bus.h> 9 #include <linux/bitfield.h> 10 #include <linux/bits.h> 11 #include <linux/dev_printk.h> 12 #include <linux/module.h> 13 #include <linux/spi/spi.h> 14 #include <linux/usb/ljca.h> 15 16 #define LJCA_SPI_BUS_MAX_HZ 48000000 17 18 #define LJCA_SPI_BUF_SIZE 60u 19 #define LJCA_SPI_MAX_XFER_SIZE \ 20 (LJCA_SPI_BUF_SIZE - sizeof(struct ljca_spi_xfer_packet)) 21 22 #define LJCA_SPI_CLK_MODE_POLARITY BIT(0) 23 #define LJCA_SPI_CLK_MODE_PHASE BIT(1) 24 25 #define LJCA_SPI_XFER_INDICATOR_ID GENMASK(5, 0) 26 #define LJCA_SPI_XFER_INDICATOR_CMPL BIT(6) 27 #define LJCA_SPI_XFER_INDICATOR_INDEX BIT(7) 28 29 /* SPI commands */ 30 enum ljca_spi_cmd { 31 LJCA_SPI_INIT = 1, 32 LJCA_SPI_READ, 33 LJCA_SPI_WRITE, 34 LJCA_SPI_WRITEREAD, 35 LJCA_SPI_DEINIT, 36 }; 37 38 enum { 39 LJCA_SPI_BUS_SPEED_24M, 40 LJCA_SPI_BUS_SPEED_12M, 41 LJCA_SPI_BUS_SPEED_8M, 42 LJCA_SPI_BUS_SPEED_6M, 43 LJCA_SPI_BUS_SPEED_4_8M, /*4.8MHz*/ 44 LJCA_SPI_BUS_SPEED_MIN = LJCA_SPI_BUS_SPEED_4_8M, 45 }; 46 47 enum { 48 LJCA_SPI_CLOCK_LOW_POLARITY, 49 LJCA_SPI_CLOCK_HIGH_POLARITY, 50 }; 51 52 enum { 53 LJCA_SPI_CLOCK_FIRST_PHASE, 54 LJCA_SPI_CLOCK_SECOND_PHASE, 55 }; 56 57 struct ljca_spi_init_packet { 58 u8 index; 59 u8 speed; 60 u8 mode; 61 } __packed; 62 63 struct ljca_spi_xfer_packet { 64 u8 indicator; 65 u8 len; 66 u8 data[] __counted_by(len); 67 } __packed; 68 69 struct ljca_spi_dev { 70 struct ljca_client *ljca; 71 struct spi_controller *controller; 72 struct ljca_spi_info *spi_info; 73 u8 speed; 74 u8 mode; 75 76 u8 obuf[LJCA_SPI_BUF_SIZE]; 77 u8 ibuf[LJCA_SPI_BUF_SIZE]; 78 }; 79 80 static int ljca_spi_read_write(struct ljca_spi_dev *ljca_spi, const u8 *w_data, 81 u8 *r_data, int len, int id, int complete, 82 int cmd) 83 { 84 struct ljca_spi_xfer_packet *w_packet = 85 (struct ljca_spi_xfer_packet *)ljca_spi->obuf; 86 struct ljca_spi_xfer_packet *r_packet = 87 (struct ljca_spi_xfer_packet *)ljca_spi->ibuf; 88 int ret; 89 90 w_packet->indicator = FIELD_PREP(LJCA_SPI_XFER_INDICATOR_ID, id) | 91 FIELD_PREP(LJCA_SPI_XFER_INDICATOR_CMPL, complete) | 92 FIELD_PREP(LJCA_SPI_XFER_INDICATOR_INDEX, 93 ljca_spi->spi_info->id); 94 95 if (cmd == LJCA_SPI_READ) { 96 w_packet->len = sizeof(u16); 97 *(__le16 *)&w_packet->data[0] = cpu_to_le16(len); 98 } else { 99 w_packet->len = len; 100 memcpy(w_packet->data, w_data, len); 101 } 102 103 ret = ljca_transfer(ljca_spi->ljca, cmd, (u8 *)w_packet, 104 struct_size(w_packet, data, w_packet->len), 105 (u8 *)r_packet, LJCA_SPI_BUF_SIZE); 106 if (ret < 0) 107 return ret; 108 else if (ret < sizeof(*r_packet) || r_packet->len <= 0) 109 return -EIO; 110 111 if (r_data) 112 memcpy(r_data, r_packet->data, r_packet->len); 113 114 return 0; 115 } 116 117 static int ljca_spi_init(struct ljca_spi_dev *ljca_spi, u8 div, u8 mode) 118 { 119 struct ljca_spi_init_packet w_packet = {}; 120 int ret; 121 122 if (ljca_spi->mode == mode && ljca_spi->speed == div) 123 return 0; 124 125 w_packet.index = ljca_spi->spi_info->id; 126 w_packet.speed = div; 127 w_packet.mode = FIELD_PREP(LJCA_SPI_CLK_MODE_POLARITY, 128 (mode & SPI_CPOL) ? LJCA_SPI_CLOCK_HIGH_POLARITY : 129 LJCA_SPI_CLOCK_LOW_POLARITY) | 130 FIELD_PREP(LJCA_SPI_CLK_MODE_PHASE, 131 (mode & SPI_CPHA) ? LJCA_SPI_CLOCK_SECOND_PHASE : 132 LJCA_SPI_CLOCK_FIRST_PHASE); 133 134 ret = ljca_transfer(ljca_spi->ljca, LJCA_SPI_INIT, (u8 *)&w_packet, 135 sizeof(w_packet), NULL, 0); 136 if (ret < 0) 137 return ret; 138 139 ljca_spi->mode = mode; 140 ljca_spi->speed = div; 141 142 return 0; 143 } 144 145 static int ljca_spi_deinit(struct ljca_spi_dev *ljca_spi) 146 { 147 struct ljca_spi_init_packet w_packet = {}; 148 int ret; 149 150 w_packet.index = ljca_spi->spi_info->id; 151 152 ret = ljca_transfer(ljca_spi->ljca, LJCA_SPI_DEINIT, (u8 *)&w_packet, 153 sizeof(w_packet), NULL, 0); 154 155 return ret < 0 ? ret : 0; 156 } 157 158 static inline int ljca_spi_transfer(struct ljca_spi_dev *ljca_spi, 159 const u8 *tx_data, u8 *rx_data, u16 len) 160 { 161 int complete, cur_len; 162 int remaining = len; 163 int cmd, ret, i; 164 int offset = 0; 165 166 if (tx_data && rx_data) 167 cmd = LJCA_SPI_WRITEREAD; 168 else if (tx_data) 169 cmd = LJCA_SPI_WRITE; 170 else if (rx_data) 171 cmd = LJCA_SPI_READ; 172 else 173 return -EINVAL; 174 175 for (i = 0; remaining > 0; i++) { 176 cur_len = min_t(unsigned int, remaining, LJCA_SPI_MAX_XFER_SIZE); 177 complete = (cur_len == remaining); 178 179 ret = ljca_spi_read_write(ljca_spi, 180 tx_data ? tx_data + offset : NULL, 181 rx_data ? rx_data + offset : NULL, 182 cur_len, i, complete, cmd); 183 if (ret) 184 return ret; 185 186 offset += cur_len; 187 remaining -= cur_len; 188 } 189 190 return 0; 191 } 192 193 static int ljca_spi_transfer_one(struct spi_controller *controller, 194 struct spi_device *spi, 195 struct spi_transfer *xfer) 196 { 197 u8 div = DIV_ROUND_UP(controller->max_speed_hz, xfer->speed_hz) / 2 - 1; 198 struct ljca_spi_dev *ljca_spi = spi_controller_get_devdata(controller); 199 int ret; 200 201 div = min_t(u8, LJCA_SPI_BUS_SPEED_MIN, div); 202 203 ret = ljca_spi_init(ljca_spi, div, spi->mode); 204 if (ret) { 205 dev_err(&ljca_spi->ljca->auxdev.dev, 206 "cannot initialize transfer ret %d\n", ret); 207 return ret; 208 } 209 210 ret = ljca_spi_transfer(ljca_spi, xfer->tx_buf, xfer->rx_buf, xfer->len); 211 if (ret) 212 dev_err(&ljca_spi->ljca->auxdev.dev, 213 "transfer failed len: %d\n", xfer->len); 214 215 return ret; 216 } 217 218 static int ljca_spi_probe(struct auxiliary_device *auxdev, 219 const struct auxiliary_device_id *aux_dev_id) 220 { 221 struct ljca_client *ljca = auxiliary_dev_to_ljca_client(auxdev); 222 struct spi_controller *controller; 223 struct ljca_spi_dev *ljca_spi; 224 int ret; 225 226 controller = devm_spi_alloc_master(&auxdev->dev, sizeof(*ljca_spi)); 227 if (!controller) 228 return -ENOMEM; 229 230 ljca_spi = spi_controller_get_devdata(controller); 231 ljca_spi->ljca = ljca; 232 ljca_spi->spi_info = dev_get_platdata(&auxdev->dev); 233 ljca_spi->controller = controller; 234 235 controller->bus_num = -1; 236 controller->mode_bits = SPI_CPHA | SPI_CPOL; 237 controller->transfer_one = ljca_spi_transfer_one; 238 controller->auto_runtime_pm = false; 239 controller->max_speed_hz = LJCA_SPI_BUS_MAX_HZ; 240 241 device_set_node(&ljca_spi->controller->dev, dev_fwnode(&auxdev->dev)); 242 auxiliary_set_drvdata(auxdev, controller); 243 244 ret = spi_register_controller(controller); 245 if (ret) 246 dev_err(&auxdev->dev, "Failed to register controller\n"); 247 248 return ret; 249 } 250 251 static void ljca_spi_dev_remove(struct auxiliary_device *auxdev) 252 { 253 struct spi_controller *controller = auxiliary_get_drvdata(auxdev); 254 struct ljca_spi_dev *ljca_spi = spi_controller_get_devdata(controller); 255 256 spi_unregister_controller(controller); 257 ljca_spi_deinit(ljca_spi); 258 } 259 260 static int ljca_spi_dev_suspend(struct device *dev) 261 { 262 struct spi_controller *controller = dev_get_drvdata(dev); 263 264 return spi_controller_suspend(controller); 265 } 266 267 static int ljca_spi_dev_resume(struct device *dev) 268 { 269 struct spi_controller *controller = dev_get_drvdata(dev); 270 271 return spi_controller_resume(controller); 272 } 273 274 static const struct dev_pm_ops ljca_spi_pm = { 275 SYSTEM_SLEEP_PM_OPS(ljca_spi_dev_suspend, ljca_spi_dev_resume) 276 }; 277 278 static const struct auxiliary_device_id ljca_spi_id_table[] = { 279 { "usb_ljca.ljca-spi", 0 }, 280 { /* sentinel */ } 281 }; 282 MODULE_DEVICE_TABLE(auxiliary, ljca_spi_id_table); 283 284 static struct auxiliary_driver ljca_spi_driver = { 285 .driver.pm = &ljca_spi_pm, 286 .probe = ljca_spi_probe, 287 .remove = ljca_spi_dev_remove, 288 .id_table = ljca_spi_id_table, 289 }; 290 module_auxiliary_driver(ljca_spi_driver); 291 292 MODULE_AUTHOR("Wentong Wu <wentong.wu@intel.com>"); 293 MODULE_AUTHOR("Zhifeng Wang <zhifeng.wang@intel.com>"); 294 MODULE_AUTHOR("Lixu Zhang <lixu.zhang@intel.com>"); 295 MODULE_DESCRIPTION("Intel La Jolla Cove Adapter USB-SPI driver"); 296 MODULE_LICENSE("GPL"); 297 MODULE_IMPORT_NS(LJCA); 298