Lines Matching +full:host +full:- +full:id
1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Copyright (C) Guenter Roeck <linux@roeck-us.net>
33 struct spi_controller *host; member
41 enum chips id; member
52 int usecs = 1000000 * len / hw->speed + 1; in sc18is602_wait_ready()
56 err = i2c_master_recv(hw->client, dummy, 1); in sc18is602_wait_ready()
61 return -ETIMEDOUT; in sc18is602_wait_ready()
67 unsigned int len = t->len; in sc18is602_txrx()
70 if (hw->tlen == 0) { in sc18is602_txrx()
72 hw->buffer[0] = 1 << spi_get_chipselect(msg->spi, 0); in sc18is602_txrx()
73 hw->tlen = 1; in sc18is602_txrx()
74 hw->rindex = 0; in sc18is602_txrx()
81 if (t->tx_buf) { in sc18is602_txrx()
82 memcpy(&hw->buffer[hw->tlen], t->tx_buf, len); in sc18is602_txrx()
83 hw->tlen += len; in sc18is602_txrx()
84 if (t->rx_buf) in sc18is602_txrx()
87 hw->rindex = hw->tlen - 1; in sc18is602_txrx()
88 } else if (t->rx_buf) { in sc18is602_txrx()
90 * For receive-only transfers we still need to perform a dummy in sc18is602_txrx()
95 hw->rindex = hw->tlen - 1; in sc18is602_txrx()
96 memset(&hw->buffer[hw->tlen], 0, len); in sc18is602_txrx()
97 hw->tlen += len; in sc18is602_txrx()
101 if (do_transfer && hw->tlen > 1) { in sc18is602_txrx()
105 ret = i2c_master_send(hw->client, hw->buffer, hw->tlen); in sc18is602_txrx()
108 if (ret != hw->tlen) in sc18is602_txrx()
109 return -EIO; in sc18is602_txrx()
111 if (t->rx_buf) { in sc18is602_txrx()
112 int rlen = hw->rindex + len; in sc18is602_txrx()
114 ret = sc18is602_wait_ready(hw, hw->tlen); in sc18is602_txrx()
117 ret = i2c_master_recv(hw->client, hw->buffer, rlen); in sc18is602_txrx()
121 return -EIO; in sc18is602_txrx()
122 memcpy(t->rx_buf, &hw->buffer[hw->rindex], len); in sc18is602_txrx()
124 hw->tlen = 0; in sc18is602_txrx()
142 if (hz >= hw->freq / 4) { in sc18is602_setup_transfer()
144 hw->speed = hw->freq / 4; in sc18is602_setup_transfer()
145 } else if (hz >= hw->freq / 16) { in sc18is602_setup_transfer()
147 hw->speed = hw->freq / 16; in sc18is602_setup_transfer()
148 } else if (hz >= hw->freq / 64) { in sc18is602_setup_transfer()
150 hw->speed = hw->freq / 64; in sc18is602_setup_transfer()
153 hw->speed = hw->freq / 128; in sc18is602_setup_transfer()
158 * value of 0xff for hw->ctrl ensures that the correct mode will be set in sc18is602_setup_transfer()
161 if (ctrl == hw->ctrl) in sc18is602_setup_transfer()
164 ret = i2c_smbus_write_byte_data(hw->client, 0xf0, ctrl); in sc18is602_setup_transfer()
168 hw->ctrl = ctrl; in sc18is602_setup_transfer()
176 if (t && t->len + tlen > SC18IS602_BUFSIZ + 1) in sc18is602_check_transfer()
177 return -EINVAL; in sc18is602_check_transfer()
182 static int sc18is602_transfer_one(struct spi_controller *host, in sc18is602_transfer_one() argument
185 struct sc18is602 *hw = spi_controller_get_devdata(host); in sc18is602_transfer_one()
186 struct spi_device *spi = m->spi; in sc18is602_transfer_one()
190 hw->tlen = 0; in sc18is602_transfer_one()
191 list_for_each_entry(t, &m->transfers, transfer_list) { in sc18is602_transfer_one()
194 status = sc18is602_check_transfer(spi, t, hw->tlen); in sc18is602_transfer_one()
198 status = sc18is602_setup_transfer(hw, t->speed_hz, spi->mode); in sc18is602_transfer_one()
202 do_transfer = t->cs_change || list_is_last(&t->transfer_list, in sc18is602_transfer_one()
203 &m->transfers); in sc18is602_transfer_one()
205 if (t->len) { in sc18is602_transfer_one()
209 m->actual_length += status; in sc18is602_transfer_one()
215 m->status = status; in sc18is602_transfer_one()
216 spi_finalize_current_message(host); in sc18is602_transfer_one()
228 struct sc18is602 *hw = spi_controller_get_devdata(spi->controller); in sc18is602_setup()
231 if (hw->id == sc18is602 && (spi_get_chipselect(spi, 0) == 2)) in sc18is602_setup()
232 return -ENXIO; in sc18is602_setup()
239 const struct i2c_device_id *id = i2c_client_get_device_id(client); in sc18is602_probe() local
240 struct device *dev = &client->dev; in sc18is602_probe()
241 struct device_node *np = dev->of_node; in sc18is602_probe()
244 struct spi_controller *host; in sc18is602_probe() local
246 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C | in sc18is602_probe()
248 return -EINVAL; in sc18is602_probe()
250 host = devm_spi_alloc_host(dev, sizeof(struct sc18is602)); in sc18is602_probe()
251 if (!host) in sc18is602_probe()
252 return -ENOMEM; in sc18is602_probe()
254 hw = spi_controller_get_devdata(host); in sc18is602_probe()
258 hw->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); in sc18is602_probe()
259 if (IS_ERR(hw->reset)) in sc18is602_probe()
260 return PTR_ERR(hw->reset); in sc18is602_probe()
261 gpiod_set_value_cansleep(hw->reset, 0); in sc18is602_probe()
263 hw->host = host; in sc18is602_probe()
264 hw->client = client; in sc18is602_probe()
265 hw->dev = dev; in sc18is602_probe()
266 hw->ctrl = 0xff; in sc18is602_probe()
268 if (client->dev.of_node) in sc18is602_probe()
269 hw->id = (uintptr_t)of_device_get_match_data(&client->dev); in sc18is602_probe()
271 hw->id = id->driver_data; in sc18is602_probe()
273 switch (hw->id) { in sc18is602_probe()
276 host->num_chipselect = 4; in sc18is602_probe()
277 hw->freq = SC18IS602_CLOCK; in sc18is602_probe()
280 host->num_chipselect = 2; in sc18is602_probe()
282 hw->freq = pdata->clock_frequency; in sc18is602_probe()
287 val = of_get_property(np, "clock-frequency", &len); in sc18is602_probe()
289 hw->freq = be32_to_cpup(val); in sc18is602_probe()
291 if (!hw->freq) in sc18is602_probe()
292 hw->freq = SC18IS602_CLOCK; in sc18is602_probe()
295 host->bus_num = np ? -1 : client->adapter->nr; in sc18is602_probe()
296 host->mode_bits = SPI_CPHA | SPI_CPOL | SPI_LSB_FIRST; in sc18is602_probe()
297 host->bits_per_word_mask = SPI_BPW_MASK(8); in sc18is602_probe()
298 host->setup = sc18is602_setup; in sc18is602_probe()
299 host->transfer_one_message = sc18is602_transfer_one; in sc18is602_probe()
300 host->max_transfer_size = sc18is602_max_transfer_size; in sc18is602_probe()
301 host->max_message_size = sc18is602_max_transfer_size; in sc18is602_probe()
302 host->dev.of_node = np; in sc18is602_probe()
303 host->min_speed_hz = hw->freq / 128; in sc18is602_probe()
304 host->max_speed_hz = hw->freq / 4; in sc18is602_probe()
306 return devm_spi_register_controller(dev, host); in sc18is602_probe()
345 MODULE_DESCRIPTION("SC18IS602/603 SPI Host Driver");