1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * ST Microelectronics MFD: stmpe's spi client specific driver 4 * 5 * Copyright (C) ST Microelectronics SA 2011 6 * 7 * Author: Viresh Kumar <vireshk@kernel.org> for ST Microelectronics 8 */ 9 10 #include <linux/spi/spi.h> 11 #include <linux/interrupt.h> 12 #include <linux/kernel.h> 13 #include <linux/module.h> 14 #include <linux/of.h> 15 #include <linux/types.h> 16 #include "stmpe.h" 17 18 #define READ_CMD (1 << 7) 19 20 static int spi_reg_read(struct stmpe *stmpe, u8 reg) 21 { 22 struct spi_device *spi = stmpe->client; 23 int status = spi_w8r16(spi, reg | READ_CMD); 24 25 return (status < 0) ? status : status >> 8; 26 } 27 28 static int spi_reg_write(struct stmpe *stmpe, u8 reg, u8 val) 29 { 30 struct spi_device *spi = stmpe->client; 31 u16 cmd = (val << 8) | reg; 32 33 return spi_write(spi, (const u8 *)&cmd, 2); 34 } 35 36 static int spi_block_read(struct stmpe *stmpe, u8 reg, u8 length, u8 *values) 37 { 38 int ret, i; 39 40 for (i = 0; i < length; i++) { 41 ret = spi_reg_read(stmpe, reg + i); 42 if (ret < 0) 43 return ret; 44 *(values + i) = ret; 45 } 46 47 return 0; 48 } 49 50 static int spi_block_write(struct stmpe *stmpe, u8 reg, u8 length, 51 const u8 *values) 52 { 53 int ret = 0, i; 54 55 for (i = length; i > 0; i--, reg++) { 56 ret = spi_reg_write(stmpe, reg, *(values + i - 1)); 57 if (ret < 0) 58 return ret; 59 } 60 61 return ret; 62 } 63 64 static void spi_init(struct stmpe *stmpe) 65 { 66 struct spi_device *spi = stmpe->client; 67 68 spi->bits_per_word = 8; 69 70 /* This register is only present for stmpe811 */ 71 if (stmpe->variant->id_val == 0x0811) 72 spi_reg_write(stmpe, STMPE811_REG_SPI_CFG, spi->mode); 73 74 if (spi_setup(spi) < 0) 75 dev_dbg(&spi->dev, "spi_setup failed\n"); 76 } 77 78 static struct stmpe_client_info spi_ci = { 79 .read_byte = spi_reg_read, 80 .write_byte = spi_reg_write, 81 .read_block = spi_block_read, 82 .write_block = spi_block_write, 83 .init = spi_init, 84 }; 85 86 static int 87 stmpe_spi_probe(struct spi_device *spi) 88 { 89 const struct spi_device_id *id = spi_get_device_id(spi); 90 91 /* don't exceed max specified rate - 1MHz - Limitation of STMPE */ 92 if (spi->max_speed_hz > 1000000) { 93 dev_dbg(&spi->dev, "f(sample) %d KHz?\n", 94 (spi->max_speed_hz/1000)); 95 return -EINVAL; 96 } 97 98 spi_ci.irq = spi->irq; 99 spi_ci.client = spi; 100 spi_ci.dev = &spi->dev; 101 102 return stmpe_probe(&spi_ci, id->driver_data); 103 } 104 105 static void stmpe_spi_remove(struct spi_device *spi) 106 { 107 struct stmpe *stmpe = spi_get_drvdata(spi); 108 109 stmpe_remove(stmpe); 110 } 111 112 static const struct of_device_id stmpe_spi_of_match[] = { 113 { .compatible = "st,stmpe610", }, 114 { .compatible = "st,stmpe801", }, 115 { .compatible = "st,stmpe811", }, 116 { .compatible = "st,stmpe1601", }, 117 { .compatible = "st,stmpe2401", }, 118 { .compatible = "st,stmpe2403", }, 119 { /* sentinel */ }, 120 }; 121 MODULE_DEVICE_TABLE(of, stmpe_spi_of_match); 122 123 static const struct spi_device_id stmpe_spi_id[] = { 124 { "stmpe610", STMPE610 }, 125 { "stmpe801", STMPE801 }, 126 { "stmpe811", STMPE811 }, 127 { "stmpe1601", STMPE1601 }, 128 { "stmpe2401", STMPE2401 }, 129 { "stmpe2403", STMPE2403 }, 130 { } 131 }; 132 MODULE_DEVICE_TABLE(spi, stmpe_id); 133 134 static struct spi_driver stmpe_spi_driver = { 135 .driver = { 136 .name = "stmpe-spi", 137 .of_match_table = of_match_ptr(stmpe_spi_of_match), 138 .pm = pm_sleep_ptr(&stmpe_dev_pm_ops), 139 }, 140 .probe = stmpe_spi_probe, 141 .remove = stmpe_spi_remove, 142 .id_table = stmpe_spi_id, 143 }; 144 145 static int __init stmpe_init(void) 146 { 147 return spi_register_driver(&stmpe_spi_driver); 148 } 149 subsys_initcall(stmpe_init); 150 151 static void __exit stmpe_exit(void) 152 { 153 spi_unregister_driver(&stmpe_spi_driver); 154 } 155 module_exit(stmpe_exit); 156 157 MODULE_DESCRIPTION("STMPE MFD SPI Interface Driver"); 158 MODULE_AUTHOR("Viresh Kumar <vireshk@kernel.org>"); 159