Lines Matching +full:clk +full:- +full:out +full:- +full:frequency

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2014 Uwe Kleine-Koenig for Pengutronix
11 #include <linux/clk.h>
13 #define DRIVER_NAME "efm32-i2c"
114 struct clk *clk; member
118 unsigned long frequency; member
130 return readl(ddata->base + offset); in efm32_i2c_read32()
136 writel(value, ddata->base + offset); in efm32_i2c_write32()
141 struct i2c_msg *cur_msg = &ddata->msgs[ddata->current_msg]; in efm32_i2c_send_next_msg()
149 struct i2c_msg *cur_msg = &ddata->msgs[ddata->current_msg]; in efm32_i2c_send_next_byte()
151 if (ddata->current_word >= cur_msg->len) { in efm32_i2c_send_next_byte()
153 ddata->current_word = 0; in efm32_i2c_send_next_byte()
154 ddata->current_msg += 1; in efm32_i2c_send_next_byte()
156 if (ddata->current_msg >= ddata->num_msgs) { in efm32_i2c_send_next_byte()
158 complete(&ddata->done); in efm32_i2c_send_next_byte()
164 cur_msg->buf[ddata->current_word++]); in efm32_i2c_send_next_byte()
170 struct i2c_msg *cur_msg = &ddata->msgs[ddata->current_msg]; in efm32_i2c_recv_next_byte()
172 cur_msg->buf[ddata->current_word] = efm32_i2c_read32(ddata, REG_RXDATA); in efm32_i2c_recv_next_byte()
173 ddata->current_word += 1; in efm32_i2c_recv_next_byte()
174 if (ddata->current_word >= cur_msg->len) { in efm32_i2c_recv_next_byte()
176 ddata->current_word = 0; in efm32_i2c_recv_next_byte()
177 ddata->current_msg += 1; in efm32_i2c_recv_next_byte()
181 if (ddata->current_msg >= ddata->num_msgs) { in efm32_i2c_recv_next_byte()
183 complete(&ddata->done); in efm32_i2c_recv_next_byte()
195 struct i2c_msg *cur_msg = &ddata->msgs[ddata->current_msg]; in efm32_i2c_irq()
204 ddata->retval = -EAGAIN; in efm32_i2c_irq()
205 complete(&ddata->done); in efm32_i2c_irq()
210 * Reset hardware state and get out in efm32_i2c_irq()
212 ddata->retval = -EIO; in efm32_i2c_irq()
216 complete(&ddata->done); in efm32_i2c_irq()
227 ddata->retval = -ENXIO; in efm32_i2c_irq()
228 complete(&ddata->done); in efm32_i2c_irq()
229 } else if (cur_msg->flags & I2C_M_RD) { in efm32_i2c_irq()
236 if (cur_msg->flags & I2C_M_RD) { in efm32_i2c_irq()
245 complete(&ddata->done); in efm32_i2c_irq()
260 if (ddata->msgs) in efm32_i2c_master_xfer()
261 return -EBUSY; in efm32_i2c_master_xfer()
263 ddata->msgs = msgs; in efm32_i2c_master_xfer()
264 ddata->num_msgs = num; in efm32_i2c_master_xfer()
265 ddata->current_word = 0; in efm32_i2c_master_xfer()
266 ddata->current_msg = 0; in efm32_i2c_master_xfer()
267 ddata->retval = -EIO; in efm32_i2c_master_xfer()
269 reinit_completion(&ddata->done); in efm32_i2c_master_xfer()
271 dev_dbg(&ddata->adapter.dev, "state: %08x, status: %08x\n", in efm32_i2c_master_xfer()
277 wait_for_completion(&ddata->done); in efm32_i2c_master_xfer()
279 if (ddata->current_msg >= ddata->num_msgs) in efm32_i2c_master_xfer()
280 ret = ddata->num_msgs; in efm32_i2c_master_xfer()
282 ret = ddata->retval; in efm32_i2c_master_xfer()
310 struct device_node *np = pdev->dev.of_node; in efm32_i2c_probe()
311 u32 location, frequency; in efm32_i2c_probe() local
315 ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL); in efm32_i2c_probe()
317 return -ENOMEM; in efm32_i2c_probe()
320 init_completion(&ddata->done); in efm32_i2c_probe()
321 strlcpy(ddata->adapter.name, pdev->name, sizeof(ddata->adapter.name)); in efm32_i2c_probe()
322 ddata->adapter.owner = THIS_MODULE; in efm32_i2c_probe()
323 ddata->adapter.algo = &efm32_i2c_algo; in efm32_i2c_probe()
324 ddata->adapter.dev.parent = &pdev->dev; in efm32_i2c_probe()
325 ddata->adapter.dev.of_node = pdev->dev.of_node; in efm32_i2c_probe()
326 i2c_set_adapdata(&ddata->adapter, ddata); in efm32_i2c_probe()
328 ddata->clk = devm_clk_get(&pdev->dev, NULL); in efm32_i2c_probe()
329 if (IS_ERR(ddata->clk)) { in efm32_i2c_probe()
330 ret = PTR_ERR(ddata->clk); in efm32_i2c_probe()
331 dev_err(&pdev->dev, "failed to get clock: %d\n", ret); in efm32_i2c_probe()
335 ddata->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); in efm32_i2c_probe()
336 if (IS_ERR(ddata->base)) in efm32_i2c_probe()
337 return PTR_ERR(ddata->base); in efm32_i2c_probe()
340 dev_err(&pdev->dev, "memory resource too small\n"); in efm32_i2c_probe()
341 return -EINVAL; in efm32_i2c_probe()
347 ret = -EINVAL; in efm32_i2c_probe()
351 ddata->irq = ret; in efm32_i2c_probe()
353 ret = clk_prepare_enable(ddata->clk); in efm32_i2c_probe()
355 dev_err(&pdev->dev, "failed to enable clock (%d)\n", ret); in efm32_i2c_probe()
367 dev_dbg(&pdev->dev, "using location %u\n", location); in efm32_i2c_probe()
372 dev_info(&pdev->dev, "fall back to location %u\n", location); in efm32_i2c_probe()
375 ddata->location = location; in efm32_i2c_probe()
377 ret = of_property_read_u32(np, "clock-frequency", &frequency); in efm32_i2c_probe()
379 dev_dbg(&pdev->dev, "using frequency %u\n", frequency); in efm32_i2c_probe()
381 frequency = I2C_MAX_STANDARD_MODE_FREQ; in efm32_i2c_probe()
382 dev_info(&pdev->dev, "defaulting to 100 kHz\n"); in efm32_i2c_probe()
384 ddata->frequency = frequency; in efm32_i2c_probe()
386 rate = clk_get_rate(ddata->clk); in efm32_i2c_probe()
388 dev_err(&pdev->dev, "there is no input clock available\n"); in efm32_i2c_probe()
389 ret = -EINVAL; in efm32_i2c_probe()
392 clkdiv = DIV_ROUND_UP(rate, 8 * ddata->frequency) - 1; in efm32_i2c_probe()
394 dev_err(&pdev->dev, in efm32_i2c_probe()
396 rate, ddata->frequency); in efm32_i2c_probe()
397 ret = -EINVAL; in efm32_i2c_probe()
401 dev_dbg(&pdev->dev, "input clock = %lu, bus freq = %lu, clkdiv = %lu\n", in efm32_i2c_probe()
402 rate, ddata->frequency, (unsigned long)clkdiv); in efm32_i2c_probe()
407 REG_ROUTE_LOCATION(ddata->location)); in efm32_i2c_probe()
419 ret = request_irq(ddata->irq, efm32_i2c_irq, 0, DRIVER_NAME, ddata); in efm32_i2c_probe()
421 dev_err(&pdev->dev, "failed to request irq (%d)\n", ret); in efm32_i2c_probe()
425 ret = i2c_add_adapter(&ddata->adapter); in efm32_i2c_probe()
427 free_irq(ddata->irq, ddata); in efm32_i2c_probe()
430 clk_disable_unprepare(ddata->clk); in efm32_i2c_probe()
439 i2c_del_adapter(&ddata->adapter); in efm32_i2c_remove()
440 free_irq(ddata->irq, ddata); in efm32_i2c_remove()
441 clk_disable_unprepare(ddata->clk); in efm32_i2c_remove()
448 .compatible = "energymicro,efm32-i2c",
466 MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>");