Lines Matching full:cci

108 struct cci;
116 struct cci *cci; member
126 struct cci { struct
138 struct cci *cci = dev; in cci_isr() local
142 val = readl(cci->base + CCI_IRQ_STATUS_0); in cci_isr()
143 writel(val, cci->base + CCI_IRQ_CLEAR_0); in cci_isr()
144 writel(0x1, cci->base + CCI_IRQ_GLOBAL_CLEAR_CMD); in cci_isr()
147 complete(&cci->master[0].irq_complete); in cci_isr()
148 if (cci->master[1].master) in cci_isr()
149 complete(&cci->master[1].irq_complete); in cci_isr()
156 cci->master[0].status = 0; in cci_isr()
157 complete(&cci->master[0].irq_complete); in cci_isr()
164 cci->master[1].status = 0; in cci_isr()
165 complete(&cci->master[1].irq_complete); in cci_isr()
180 writel(reset, cci->base + CCI_RESET_CMD); in cci_isr()
185 cci->master[0].status = -ENXIO; in cci_isr()
187 cci->master[0].status = -EIO; in cci_isr()
189 writel(CCI_HALT_REQ_I2C_M0_Q0Q1, cci->base + CCI_HALT_REQ); in cci_isr()
196 cci->master[1].status = -ENXIO; in cci_isr()
198 cci->master[1].status = -EIO; in cci_isr()
200 writel(CCI_HALT_REQ_I2C_M1_Q0Q1, cci->base + CCI_HALT_REQ); in cci_isr()
207 static int cci_halt(struct cci *cci, u8 master_num) in cci_halt() argument
212 if (master_num >= cci->data->num_masters) { in cci_halt()
213 dev_err(cci->dev, "Unsupported master idx (%u)\n", master_num); in cci_halt()
218 master = &cci->master[master_num]; in cci_halt()
221 writel(val, cci->base + CCI_HALT_REQ); in cci_halt()
224 dev_err(cci->dev, "CCI halt timeout\n"); in cci_halt()
231 static int cci_reset(struct cci *cci) in cci_reset() argument
237 reinit_completion(&cci->master[0].irq_complete); in cci_reset()
238 writel(CCI_RESET_CMD_MASK, cci->base + CCI_RESET_CMD); in cci_reset()
240 if (!wait_for_completion_timeout(&cci->master[0].irq_complete, in cci_reset()
242 dev_err(cci->dev, "CCI reset timeout\n"); in cci_reset()
249 static int cci_init(struct cci *cci) in cci_init() argument
264 writel(val, cci->base + CCI_IRQ_MASK_0); in cci_init()
266 for (i = 0; i < cci->data->num_masters; i++) { in cci_init()
267 int mode = cci->master[i].mode; in cci_init()
270 if (!cci->master[i].cci) in cci_init()
273 hw = &cci->data->params[mode]; in cci_init()
276 writel(val, cci->base + CCI_I2C_Mm_SCL_CTL(i)); in cci_init()
279 writel(val, cci->base + CCI_I2C_Mm_SDA_CTL_0(i)); in cci_init()
282 writel(val, cci->base + CCI_I2C_Mm_SDA_CTL_1(i)); in cci_init()
285 writel(val, cci->base + CCI_I2C_Mm_SDA_CTL_2(i)); in cci_init()
288 writel(val, cci->base + CCI_I2C_Mm_MISC_CTL(i)); in cci_init()
294 static int cci_run_queue(struct cci *cci, u8 master, u8 queue) in cci_run_queue() argument
298 val = readl(cci->base + CCI_I2C_Mm_Qn_CUR_WORD_CNT(master, queue)); in cci_run_queue()
299 writel(val, cci->base + CCI_I2C_Mm_Qn_EXEC_WORD_CNT(master, queue)); in cci_run_queue()
301 reinit_completion(&cci->master[master].irq_complete); in cci_run_queue()
303 writel(val, cci->base + CCI_QUEUE_START); in cci_run_queue()
305 if (!wait_for_completion_timeout(&cci->master[master].irq_complete, in cci_run_queue()
307 dev_err(cci->dev, "master %d queue %d timeout\n", in cci_run_queue()
309 cci_reset(cci); in cci_run_queue()
310 cci_init(cci); in cci_run_queue()
314 return cci->master[master].status; in cci_run_queue()
317 static int cci_validate_queue(struct cci *cci, u8 master, u8 queue) in cci_validate_queue() argument
321 val = readl(cci->base + CCI_I2C_Mm_Qn_CUR_WORD_CNT(master, queue)); in cci_validate_queue()
322 if (val == cci->data->queue_size[queue]) in cci_validate_queue()
329 writel(val, cci->base + CCI_I2C_Mm_Qn_LOAD_DATA(master, queue)); in cci_validate_queue()
331 return cci_run_queue(cci, master, queue); in cci_validate_queue()
334 static int cci_i2c_read(struct cci *cci, u16 master, in cci_i2c_read() argument
346 ret = cci_validate_queue(cci, master, queue); in cci_i2c_read()
351 writel(val, cci->base + CCI_I2C_Mm_Qn_LOAD_DATA(master, queue)); in cci_i2c_read()
354 writel(val, cci->base + CCI_I2C_Mm_Qn_LOAD_DATA(master, queue)); in cci_i2c_read()
356 ret = cci_run_queue(cci, master, queue); in cci_i2c_read()
360 words_read = readl(cci->base + CCI_I2C_Mm_READ_BUF_LEVEL(master)); in cci_i2c_read()
363 dev_err(cci->dev, "words read = %d, words expected = %d\n", in cci_i2c_read()
369 val = readl(cci->base + CCI_I2C_Mm_READ_DATA(master)); in cci_i2c_read()
387 static int cci_i2c_write(struct cci *cci, u16 master, in cci_i2c_write() argument
399 ret = cci_validate_queue(cci, master, queue); in cci_i2c_write()
404 writel(val, cci->base + CCI_I2C_Mm_Qn_LOAD_DATA(master, queue)); in cci_i2c_write()
416 writel(val, cci->base + CCI_I2C_Mm_Qn_LOAD_DATA(master, queue)); in cci_i2c_write()
420 writel(val, cci->base + CCI_I2C_Mm_Qn_LOAD_DATA(master, queue)); in cci_i2c_write()
422 return cci_run_queue(cci, master, queue); in cci_i2c_write()
428 struct cci *cci = cci_master->cci; in cci_xfer() local
431 ret = pm_runtime_get_sync(cci->dev); in cci_xfer()
437 ret = cci_i2c_read(cci, cci_master->master, in cci_xfer()
441 ret = cci_i2c_write(cci, cci_master->master, in cci_xfer()
453 pm_runtime_mark_last_busy(cci->dev); in cci_xfer()
454 pm_runtime_put_autosuspend(cci->dev); in cci_xfer()
469 static int cci_enable_clocks(struct cci *cci) in cci_enable_clocks() argument
471 return clk_bulk_prepare_enable(cci->nclocks, cci->clocks); in cci_enable_clocks()
474 static void cci_disable_clocks(struct cci *cci) in cci_disable_clocks() argument
476 clk_bulk_disable_unprepare(cci->nclocks, cci->clocks); in cci_disable_clocks()
481 struct cci *cci = dev_get_drvdata(dev); in cci_suspend_runtime() local
483 cci_disable_clocks(cci); in cci_suspend_runtime()
489 struct cci *cci = dev_get_drvdata(dev); in cci_resume_runtime() local
492 ret = cci_enable_clocks(cci); in cci_resume_runtime()
496 cci_init(cci); in cci_resume_runtime()
527 struct cci *cci; in cci_probe() local
531 cci = devm_kzalloc(dev, sizeof(*cci), GFP_KERNEL); in cci_probe()
532 if (!cci) in cci_probe()
535 cci->dev = dev; in cci_probe()
536 platform_set_drvdata(pdev, cci); in cci_probe()
537 cci->data = device_get_match_data(dev); in cci_probe()
538 if (!cci->data) in cci_probe()
551 if (idx >= cci->data->num_masters) { in cci_probe()
553 child, idx, cci->data->num_masters - 1); in cci_probe()
557 master = &cci->master[idx]; in cci_probe()
558 master->adap.quirks = &cci->data->quirks; in cci_probe()
563 master->cci = cci; in cci_probe()
566 snprintf(master->adap.name, sizeof(master->adap.name), "Qualcomm-CCI"); in cci_probe()
582 cci->base = devm_platform_get_and_ioremap_resource(pdev, 0, &r); in cci_probe()
583 if (IS_ERR(cci->base)) in cci_probe()
584 return PTR_ERR(cci->base); in cci_probe()
588 ret = devm_clk_bulk_get_all(dev, &cci->clocks); in cci_probe()
593 cci->nclocks = ret; in cci_probe()
595 ret = cci_enable_clocks(cci); in cci_probe()
604 cci->irq = ret; in cci_probe()
606 ret = devm_request_irq(dev, cci->irq, cci_isr, 0, dev_name(dev), cci); in cci_probe()
612 val = readl(cci->base + CCI_HW_VERSION); in cci_probe()
613 dev_dbg(dev, "CCI HW version = 0x%08x", val); in cci_probe()
615 ret = cci_reset(cci); in cci_probe()
619 ret = cci_init(cci); in cci_probe()
628 for (i = 0; i < cci->data->num_masters; i++) { in cci_probe()
629 if (!cci->master[i].cci) in cci_probe()
632 ret = i2c_add_adapter(&cci->master[i].adap); in cci_probe()
634 of_node_put(cci->master[i].adap.dev.of_node); in cci_probe()
646 if (cci->master[i].cci) { in cci_probe()
647 i2c_del_adapter(&cci->master[i].adap); in cci_probe()
648 of_node_put(cci->master[i].adap.dev.of_node); in cci_probe()
652 disable_irq(cci->irq); in cci_probe()
654 cci_disable_clocks(cci); in cci_probe()
661 struct cci *cci = platform_get_drvdata(pdev); in cci_remove() local
664 for (i = 0; i < cci->data->num_masters; i++) { in cci_remove()
665 if (cci->master[i].cci) { in cci_remove()
666 i2c_del_adapter(&cci->master[i].adap); in cci_remove()
667 of_node_put(cci->master[i].adap.dev.of_node); in cci_remove()
669 cci_halt(cci, i); in cci_remove()
672 disable_irq(cci->irq); in cci_remove()
789 { .compatible = "qcom,msm8226-cci", .data = &cci_v1_data},
790 { .compatible = "qcom,msm8974-cci", .data = &cci_v1_5_data},
791 { .compatible = "qcom,msm8996-cci", .data = &cci_v2_data},
798 { .compatible = "qcom,msm8916-cci", .data = &cci_v1_data},
799 { .compatible = "qcom,sdm845-cci", .data = &cci_v2_data},
800 { .compatible = "qcom,sm8250-cci", .data = &cci_v2_data},
801 { .compatible = "qcom,sm8450-cci", .data = &cci_v2_data},
810 .name = "i2c-qcom-cci",