Lines Matching +full:ctrl +full:- +full:len
1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Copyright (C) Guenter Roeck <linux@roeck-us.net>
37 u8 ctrl; member
51 static int sc18is602_wait_ready(struct sc18is602 *hw, int len) in sc18is602_wait_ready() argument
54 int usecs = 1000000 * len / hw->speed + 1; in sc18is602_wait_ready()
58 err = i2c_master_recv(hw->client, dummy, 1); in sc18is602_wait_ready()
63 return -ETIMEDOUT; in sc18is602_wait_ready()
69 unsigned int len = t->len; in sc18is602_txrx() local
72 if (hw->tlen == 0) { in sc18is602_txrx()
74 hw->buffer[0] = 1 << spi_get_chipselect(msg->spi, 0); in sc18is602_txrx()
75 hw->tlen = 1; in sc18is602_txrx()
76 hw->rindex = 0; in sc18is602_txrx()
83 if (t->tx_buf) { in sc18is602_txrx()
84 memcpy(&hw->buffer[hw->tlen], t->tx_buf, len); in sc18is602_txrx()
85 hw->tlen += len; in sc18is602_txrx()
86 if (t->rx_buf) in sc18is602_txrx()
89 hw->rindex = hw->tlen - 1; in sc18is602_txrx()
90 } else if (t->rx_buf) { in sc18is602_txrx()
92 * For receive-only transfers we still need to perform a dummy in sc18is602_txrx()
97 hw->rindex = hw->tlen - 1; in sc18is602_txrx()
98 memset(&hw->buffer[hw->tlen], 0, len); in sc18is602_txrx()
99 hw->tlen += len; in sc18is602_txrx()
103 if (do_transfer && hw->tlen > 1) { in sc18is602_txrx()
107 ret = i2c_master_send(hw->client, hw->buffer, hw->tlen); in sc18is602_txrx()
110 if (ret != hw->tlen) in sc18is602_txrx()
111 return -EIO; in sc18is602_txrx()
113 if (t->rx_buf) { in sc18is602_txrx()
114 int rlen = hw->rindex + len; in sc18is602_txrx()
116 ret = sc18is602_wait_ready(hw, hw->tlen); in sc18is602_txrx()
119 ret = i2c_master_recv(hw->client, hw->buffer, rlen); in sc18is602_txrx()
123 return -EIO; in sc18is602_txrx()
124 memcpy(t->rx_buf, &hw->buffer[hw->rindex], len); in sc18is602_txrx()
126 hw->tlen = 0; in sc18is602_txrx()
128 return len; in sc18is602_txrx()
133 u8 ctrl = 0; in sc18is602_setup_transfer() local
137 ctrl |= SC18IS602_MODE_CPHA; in sc18is602_setup_transfer()
139 ctrl |= SC18IS602_MODE_CPOL; in sc18is602_setup_transfer()
141 ctrl |= SC18IS602_MODE_LSB_FIRST; in sc18is602_setup_transfer()
144 if (hz >= hw->freq / 4) { in sc18is602_setup_transfer()
145 ctrl |= SC18IS602_MODE_CLOCK_DIV_4; in sc18is602_setup_transfer()
146 hw->speed = hw->freq / 4; in sc18is602_setup_transfer()
147 } else if (hz >= hw->freq / 16) { in sc18is602_setup_transfer()
148 ctrl |= SC18IS602_MODE_CLOCK_DIV_16; in sc18is602_setup_transfer()
149 hw->speed = hw->freq / 16; in sc18is602_setup_transfer()
150 } else if (hz >= hw->freq / 64) { in sc18is602_setup_transfer()
151 ctrl |= SC18IS602_MODE_CLOCK_DIV_64; in sc18is602_setup_transfer()
152 hw->speed = hw->freq / 64; in sc18is602_setup_transfer()
154 ctrl |= SC18IS602_MODE_CLOCK_DIV_128; in sc18is602_setup_transfer()
155 hw->speed = hw->freq / 128; in sc18is602_setup_transfer()
160 * value of 0xff for hw->ctrl ensures that the correct mode will be set in sc18is602_setup_transfer()
163 if (ctrl == hw->ctrl) in sc18is602_setup_transfer()
166 ret = i2c_smbus_write_byte_data(hw->client, 0xf0, ctrl); in sc18is602_setup_transfer()
170 hw->ctrl = ctrl; in sc18is602_setup_transfer()
178 if (t && t->len + tlen > SC18IS602_BUFSIZ + 1) in sc18is602_check_transfer()
179 return -EINVAL; in sc18is602_check_transfer()
188 struct spi_device *spi = m->spi; in sc18is602_transfer_one()
192 hw->tlen = 0; in sc18is602_transfer_one()
193 list_for_each_entry(t, &m->transfers, transfer_list) { in sc18is602_transfer_one()
196 status = sc18is602_check_transfer(spi, t, hw->tlen); in sc18is602_transfer_one()
200 status = sc18is602_setup_transfer(hw, t->speed_hz, spi->mode); in sc18is602_transfer_one()
204 do_transfer = t->cs_change || list_is_last(&t->transfer_list, in sc18is602_transfer_one()
205 &m->transfers); in sc18is602_transfer_one()
207 if (t->len) { in sc18is602_transfer_one()
211 m->actual_length += status; in sc18is602_transfer_one()
217 m->status = status; in sc18is602_transfer_one()
230 struct sc18is602 *hw = spi_controller_get_devdata(spi->controller); in sc18is602_setup()
233 if (hw->id == sc18is602 && (spi_get_chipselect(spi, 0) == 2)) in sc18is602_setup()
234 return -ENXIO; in sc18is602_setup()
241 struct device *dev = &client->dev; in sc18is602_probe()
246 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C | in sc18is602_probe()
248 return -EINVAL; in sc18is602_probe()
252 return -ENOMEM; in sc18is602_probe()
254 device_set_node(&host->dev, dev_fwnode(dev)); in sc18is602_probe()
259 hw->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); in sc18is602_probe()
260 if (IS_ERR(hw->reset)) in sc18is602_probe()
261 return PTR_ERR(hw->reset); in sc18is602_probe()
262 gpiod_set_value_cansleep(hw->reset, 0); in sc18is602_probe()
264 hw->host = host; in sc18is602_probe()
265 hw->client = client; in sc18is602_probe()
266 hw->dev = dev; in sc18is602_probe()
267 hw->ctrl = 0xff; in sc18is602_probe()
269 hw->id = (uintptr_t)i2c_get_match_data(client); in sc18is602_probe()
270 switch (hw->id) { in sc18is602_probe()
273 host->num_chipselect = 4; in sc18is602_probe()
274 hw->freq = SC18IS602_CLOCK; in sc18is602_probe()
277 host->num_chipselect = 2; in sc18is602_probe()
279 hw->freq = pdata->clock_frequency; in sc18is602_probe()
281 device_property_read_u32(dev, "clock-frequency", &hw->freq); in sc18is602_probe()
282 if (!hw->freq) in sc18is602_probe()
283 hw->freq = SC18IS602_CLOCK; in sc18is602_probe()
286 host->bus_num = dev_fwnode(dev) ? -1 : client->adapter->nr; in sc18is602_probe()
287 host->mode_bits = SPI_CPHA | SPI_CPOL | SPI_LSB_FIRST; in sc18is602_probe()
288 host->bits_per_word_mask = SPI_BPW_MASK(8); in sc18is602_probe()
289 host->setup = sc18is602_setup; in sc18is602_probe()
290 host->transfer_one_message = sc18is602_transfer_one; in sc18is602_probe()
291 host->max_transfer_size = sc18is602_max_transfer_size; in sc18is602_probe()
292 host->max_message_size = sc18is602_max_transfer_size; in sc18is602_probe()
293 host->min_speed_hz = hw->freq / 128; in sc18is602_probe()
294 host->max_speed_hz = hw->freq / 4; in sc18is602_probe()