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>
36 u8 ctrl; member
50 static int sc18is602_wait_ready(struct sc18is602 *hw, int len) in sc18is602_wait_ready() argument
53 int usecs = 1000000 * len / hw->speed + 1; in sc18is602_wait_ready()
57 err = i2c_master_recv(hw->client, dummy, 1); in sc18is602_wait_ready()
62 return -ETIMEDOUT; in sc18is602_wait_ready()
68 unsigned int len = t->len; in sc18is602_txrx() local
71 if (hw->tlen == 0) { in sc18is602_txrx()
73 hw->buffer[0] = 1 << msg->spi->chip_select; in sc18is602_txrx()
74 hw->tlen = 1; in sc18is602_txrx()
75 hw->rindex = 0; in sc18is602_txrx()
82 if (t->tx_buf) { in sc18is602_txrx()
83 memcpy(&hw->buffer[hw->tlen], t->tx_buf, len); in sc18is602_txrx()
84 hw->tlen += len; in sc18is602_txrx()
85 if (t->rx_buf) in sc18is602_txrx()
88 hw->rindex = hw->tlen - 1; in sc18is602_txrx()
89 } else if (t->rx_buf) { in sc18is602_txrx()
91 * For receive-only transfers we still need to perform a dummy in sc18is602_txrx()
96 hw->rindex = hw->tlen - 1; in sc18is602_txrx()
97 memset(&hw->buffer[hw->tlen], 0, len); in sc18is602_txrx()
98 hw->tlen += len; in sc18is602_txrx()
102 if (do_transfer && hw->tlen > 1) { in sc18is602_txrx()
106 ret = i2c_master_send(hw->client, hw->buffer, hw->tlen); in sc18is602_txrx()
109 if (ret != hw->tlen) in sc18is602_txrx()
110 return -EIO; in sc18is602_txrx()
112 if (t->rx_buf) { in sc18is602_txrx()
113 int rlen = hw->rindex + len; in sc18is602_txrx()
115 ret = sc18is602_wait_ready(hw, hw->tlen); in sc18is602_txrx()
118 ret = i2c_master_recv(hw->client, hw->buffer, rlen); in sc18is602_txrx()
122 return -EIO; in sc18is602_txrx()
123 memcpy(t->rx_buf, &hw->buffer[hw->rindex], len); in sc18is602_txrx()
125 hw->tlen = 0; in sc18is602_txrx()
127 return len; in sc18is602_txrx()
132 u8 ctrl = 0; in sc18is602_setup_transfer() local
136 ctrl |= SC18IS602_MODE_CPHA; in sc18is602_setup_transfer()
138 ctrl |= SC18IS602_MODE_CPOL; in sc18is602_setup_transfer()
140 ctrl |= SC18IS602_MODE_LSB_FIRST; in sc18is602_setup_transfer()
143 if (hz >= hw->freq / 4) { in sc18is602_setup_transfer()
144 ctrl |= SC18IS602_MODE_CLOCK_DIV_4; in sc18is602_setup_transfer()
145 hw->speed = hw->freq / 4; in sc18is602_setup_transfer()
146 } else if (hz >= hw->freq / 16) { in sc18is602_setup_transfer()
147 ctrl |= SC18IS602_MODE_CLOCK_DIV_16; in sc18is602_setup_transfer()
148 hw->speed = hw->freq / 16; in sc18is602_setup_transfer()
149 } else if (hz >= hw->freq / 64) { in sc18is602_setup_transfer()
150 ctrl |= SC18IS602_MODE_CLOCK_DIV_64; in sc18is602_setup_transfer()
151 hw->speed = hw->freq / 64; in sc18is602_setup_transfer()
153 ctrl |= SC18IS602_MODE_CLOCK_DIV_128; in sc18is602_setup_transfer()
154 hw->speed = hw->freq / 128; in sc18is602_setup_transfer()
159 * value of 0xff for hw->ctrl ensures that the correct mode will be set in sc18is602_setup_transfer()
162 if (ctrl == hw->ctrl) in sc18is602_setup_transfer()
165 ret = i2c_smbus_write_byte_data(hw->client, 0xf0, ctrl); in sc18is602_setup_transfer()
169 hw->ctrl = ctrl; in sc18is602_setup_transfer()
177 if (t && t->len + tlen > SC18IS602_BUFSIZ + 1) in sc18is602_check_transfer()
178 return -EINVAL; in sc18is602_check_transfer()
187 struct spi_device *spi = m->spi; in sc18is602_transfer_one()
191 hw->tlen = 0; in sc18is602_transfer_one()
192 list_for_each_entry(t, &m->transfers, transfer_list) { in sc18is602_transfer_one()
195 status = sc18is602_check_transfer(spi, t, hw->tlen); in sc18is602_transfer_one()
199 status = sc18is602_setup_transfer(hw, t->speed_hz, spi->mode); in sc18is602_transfer_one()
203 do_transfer = t->cs_change || list_is_last(&t->transfer_list, in sc18is602_transfer_one()
204 &m->transfers); in sc18is602_transfer_one()
206 if (t->len) { in sc18is602_transfer_one()
210 m->actual_length += status; in sc18is602_transfer_one()
216 m->status = status; in sc18is602_transfer_one()
229 struct sc18is602 *hw = spi_master_get_devdata(spi->master); in sc18is602_setup()
232 if (hw->id == sc18is602 && spi->chip_select == 2) in sc18is602_setup()
233 return -ENXIO; in sc18is602_setup()
241 struct device *dev = &client->dev; in sc18is602_probe()
242 struct device_node *np = dev->of_node; in sc18is602_probe()
247 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C | in sc18is602_probe()
249 return -EINVAL; in sc18is602_probe()
253 return -ENOMEM; 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->master = master; 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 if (client->dev.of_node) in sc18is602_probe()
270 hw->id = (enum chips)of_device_get_match_data(&client->dev); in sc18is602_probe()
272 hw->id = id->driver_data; in sc18is602_probe()
274 switch (hw->id) { in sc18is602_probe()
277 master->num_chipselect = 4; in sc18is602_probe()
278 hw->freq = SC18IS602_CLOCK; in sc18is602_probe()
281 master->num_chipselect = 2; in sc18is602_probe()
283 hw->freq = pdata->clock_frequency; in sc18is602_probe()
286 int len; in sc18is602_probe() local
288 val = of_get_property(np, "clock-frequency", &len); in sc18is602_probe()
289 if (val && len >= sizeof(__be32)) in sc18is602_probe()
290 hw->freq = be32_to_cpup(val); in sc18is602_probe()
292 if (!hw->freq) in sc18is602_probe()
293 hw->freq = SC18IS602_CLOCK; in sc18is602_probe()
296 master->bus_num = np ? -1 : client->adapter->nr; in sc18is602_probe()
297 master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_LSB_FIRST; in sc18is602_probe()
298 master->bits_per_word_mask = SPI_BPW_MASK(8); in sc18is602_probe()
299 master->setup = sc18is602_setup; in sc18is602_probe()
300 master->transfer_one_message = sc18is602_transfer_one; in sc18is602_probe()
301 master->max_transfer_size = sc18is602_max_transfer_size; in sc18is602_probe()
302 master->max_message_size = sc18is602_max_transfer_size; in sc18is602_probe()
303 master->dev.of_node = np; in sc18is602_probe()
304 master->min_speed_hz = hw->freq / 128; in sc18is602_probe()
305 master->max_speed_hz = hw->freq / 4; in sc18is602_probe()