Lines Matching refs:core

36 static int si476x_core_config_pinmux(struct si476x_core *core)  in si476x_core_config_pinmux()  argument
39 dev_dbg(&core->client->dev, "Configuring pinmux\n"); in si476x_core_config_pinmux()
40 err = si476x_core_cmd_dig_audio_pin_cfg(core, in si476x_core_config_pinmux()
41 core->pinmux.dclk, in si476x_core_config_pinmux()
42 core->pinmux.dfs, in si476x_core_config_pinmux()
43 core->pinmux.dout, in si476x_core_config_pinmux()
44 core->pinmux.xout); in si476x_core_config_pinmux()
46 dev_err(&core->client->dev, in si476x_core_config_pinmux()
52 err = si476x_core_cmd_zif_pin_cfg(core, in si476x_core_config_pinmux()
53 core->pinmux.iqclk, in si476x_core_config_pinmux()
54 core->pinmux.iqfs, in si476x_core_config_pinmux()
55 core->pinmux.iout, in si476x_core_config_pinmux()
56 core->pinmux.qout); in si476x_core_config_pinmux()
58 dev_err(&core->client->dev, in si476x_core_config_pinmux()
64 err = si476x_core_cmd_ic_link_gpo_ctl_pin_cfg(core, in si476x_core_config_pinmux()
65 core->pinmux.icin, in si476x_core_config_pinmux()
66 core->pinmux.icip, in si476x_core_config_pinmux()
67 core->pinmux.icon, in si476x_core_config_pinmux()
68 core->pinmux.icop); in si476x_core_config_pinmux()
70 dev_err(&core->client->dev, in si476x_core_config_pinmux()
76 err = si476x_core_cmd_ana_audio_pin_cfg(core, in si476x_core_config_pinmux()
77 core->pinmux.lrout); in si476x_core_config_pinmux()
79 dev_err(&core->client->dev, in si476x_core_config_pinmux()
85 err = si476x_core_cmd_intb_pin_cfg(core, in si476x_core_config_pinmux()
86 core->pinmux.intb, in si476x_core_config_pinmux()
87 core->pinmux.a1); in si476x_core_config_pinmux()
89 dev_err(&core->client->dev, in si476x_core_config_pinmux()
98 static inline void si476x_core_schedule_polling_work(struct si476x_core *core) in si476x_core_schedule_polling_work() argument
100 schedule_delayed_work(&core->status_monitor, in si476x_core_schedule_polling_work()
127 int si476x_core_start(struct si476x_core *core, bool soft) in si476x_core_start() argument
129 struct i2c_client *client = core->client; in si476x_core_start()
133 if (gpio_is_valid(core->gpio_reset)) in si476x_core_start()
134 gpio_set_value_cansleep(core->gpio_reset, 1); in si476x_core_start()
142 atomic_set(&core->is_alive, 1); in si476x_core_start()
143 si476x_core_schedule_polling_work(core); in si476x_core_start()
149 atomic_set(&core->is_alive, 1); in si476x_core_start()
150 si476x_core_schedule_polling_work(core); in si476x_core_start()
154 err = si476x_core_cmd_power_up(core, in si476x_core_start()
155 &core->power_up_parameters); in si476x_core_start()
158 dev_err(&core->client->dev, in si476x_core_start()
165 atomic_set(&core->is_alive, 1); in si476x_core_start()
167 err = si476x_core_config_pinmux(core); in si476x_core_start()
169 dev_err(&core->client->dev, in si476x_core_start()
176 err = regmap_write(core->regmap, in si476x_core_start()
182 dev_err(&core->client->dev, in si476x_core_start()
193 atomic_set(&core->is_alive, 0); in si476x_core_start()
198 cancel_delayed_work_sync(&core->status_monitor); in si476x_core_start()
200 if (gpio_is_valid(core->gpio_reset)) in si476x_core_start()
201 gpio_set_value_cansleep(core->gpio_reset, 0); in si476x_core_start()
221 int si476x_core_stop(struct si476x_core *core, bool soft) in si476x_core_stop() argument
224 atomic_set(&core->is_alive, 0); in si476x_core_stop()
234 err = si476x_core_cmd_power_down(core, &args); in si476x_core_stop()
240 if (core->client->irq) in si476x_core_stop()
241 disable_irq(core->client->irq); in si476x_core_stop()
243 cancel_delayed_work_sync(&core->status_monitor); in si476x_core_stop()
246 if (gpio_is_valid(core->gpio_reset)) in si476x_core_stop()
247 gpio_set_value_cansleep(core->gpio_reset, 0); in si476x_core_stop()
265 int si476x_core_set_power_state(struct si476x_core *core, in si476x_core_set_power_state() argument
275 if (core->power_state == SI476X_POWER_INCONSISTENT) { in si476x_core_set_power_state()
276 dev_err(&core->client->dev, in si476x_core_set_power_state()
281 if (next_state != core->power_state) { in si476x_core_set_power_state()
284 err = regulator_bulk_enable(ARRAY_SIZE(core->supplies), in si476x_core_set_power_state()
285 core->supplies); in si476x_core_set_power_state()
287 core->power_state = SI476X_POWER_INCONSISTENT; in si476x_core_set_power_state()
297 err = si476x_core_start(core, false); in si476x_core_set_power_state()
301 core->power_state = next_state; in si476x_core_set_power_state()
305 core->power_state = next_state; in si476x_core_set_power_state()
306 err = si476x_core_stop(core, false); in si476x_core_set_power_state()
308 core->power_state = SI476X_POWER_INCONSISTENT; in si476x_core_set_power_state()
310 err = regulator_bulk_disable(ARRAY_SIZE(core->supplies), in si476x_core_set_power_state()
311 core->supplies); in si476x_core_set_power_state()
313 core->power_state = SI476X_POWER_INCONSISTENT; in si476x_core_set_power_state()
330 static inline void si476x_core_report_drainer_stop(struct si476x_core *core) in si476x_core_report_drainer_stop() argument
332 mutex_lock(&core->rds_drainer_status_lock); in si476x_core_report_drainer_stop()
333 core->rds_drainer_is_working = false; in si476x_core_report_drainer_stop()
334 mutex_unlock(&core->rds_drainer_status_lock); in si476x_core_report_drainer_stop()
343 static inline void si476x_core_start_rds_drainer_once(struct si476x_core *core) in si476x_core_start_rds_drainer_once() argument
345 mutex_lock(&core->rds_drainer_status_lock); in si476x_core_start_rds_drainer_once()
346 if (!core->rds_drainer_is_working) { in si476x_core_start_rds_drainer_once()
347 core->rds_drainer_is_working = true; in si476x_core_start_rds_drainer_once()
348 schedule_work(&core->rds_fifo_drainer); in si476x_core_start_rds_drainer_once()
350 mutex_unlock(&core->rds_drainer_status_lock); in si476x_core_start_rds_drainer_once()
363 struct si476x_core *core = container_of(work, struct si476x_core, in si476x_core_drain_rds_fifo() local
368 si476x_core_lock(core); in si476x_core_drain_rds_fifo()
369 err = si476x_core_cmd_fm_rds_status(core, true, false, false, &report); in si476x_core_drain_rds_fifo()
372 dev_dbg(&core->client->dev, in si476x_core_drain_rds_fifo()
375 err = si476x_core_cmd_fm_rds_status(core, false, false, in si476x_core_drain_rds_fifo()
380 kfifo_in(&core->rds_fifo, report.rds, in si476x_core_drain_rds_fifo()
382 dev_dbg(&core->client->dev, "RDS data:\n %*ph\n", in si476x_core_drain_rds_fifo()
385 dev_dbg(&core->client->dev, "Drrrrained!\n"); in si476x_core_drain_rds_fifo()
386 wake_up_interruptible(&core->rds_read_queue); in si476x_core_drain_rds_fifo()
390 si476x_core_unlock(core); in si476x_core_drain_rds_fifo()
391 si476x_core_report_drainer_stop(core); in si476x_core_drain_rds_fifo()
403 static void si476x_core_pronounce_dead(struct si476x_core *core) in si476x_core_pronounce_dead() argument
405 dev_info(&core->client->dev, "Core device is dead.\n"); in si476x_core_pronounce_dead()
407 atomic_set(&core->is_alive, 0); in si476x_core_pronounce_dead()
410 wake_up_interruptible(&core->rds_read_queue); in si476x_core_pronounce_dead()
412 atomic_set(&core->cts, 1); in si476x_core_pronounce_dead()
413 wake_up(&core->command); in si476x_core_pronounce_dead()
415 atomic_set(&core->stc, 1); in si476x_core_pronounce_dead()
416 wake_up(&core->tuning); in si476x_core_pronounce_dead()
434 int si476x_core_i2c_xfer(struct si476x_core *core, in si476x_core_i2c_xfer() argument
441 err = i2c_master_send(core->client, buf, count); in si476x_core_i2c_xfer()
443 err = i2c_master_recv(core->client, buf, count); in si476x_core_i2c_xfer()
447 si476x_core_pronounce_dead(core); in si476x_core_i2c_xfer()
466 static int si476x_core_get_status(struct si476x_core *core) in si476x_core_get_status() argument
469 int err = si476x_core_i2c_xfer(core, SI476X_I2C_RECV, in si476x_core_get_status()
483 static void si476x_core_get_and_signal_status(struct si476x_core *core) in si476x_core_get_and_signal_status() argument
485 int status = si476x_core_get_status(core); in si476x_core_get_and_signal_status()
487 dev_err(&core->client->dev, "Failed to get status\n"); in si476x_core_get_and_signal_status()
498 dev_dbg(&core->client->dev, "[interrupt] CTSINT\n"); in si476x_core_get_and_signal_status()
499 atomic_set(&core->cts, 1); in si476x_core_get_and_signal_status()
500 wake_up(&core->command); in si476x_core_get_and_signal_status()
504 dev_dbg(&core->client->dev, "[interrupt] RDSINT\n"); in si476x_core_get_and_signal_status()
505 si476x_core_start_rds_drainer_once(core); in si476x_core_get_and_signal_status()
509 dev_dbg(&core->client->dev, "[interrupt] STCINT\n"); in si476x_core_get_and_signal_status()
510 atomic_set(&core->stc, 1); in si476x_core_get_and_signal_status()
511 wake_up(&core->tuning); in si476x_core_get_and_signal_status()
517 struct si476x_core *core = SI476X_WORK_TO_CORE(work); in si476x_core_poll_loop() local
519 si476x_core_get_and_signal_status(core); in si476x_core_poll_loop()
521 if (atomic_read(&core->is_alive)) in si476x_core_poll_loop()
522 si476x_core_schedule_polling_work(core); in si476x_core_poll_loop()
527 struct si476x_core *core = dev; in si476x_core_interrupt() local
529 si476x_core_get_and_signal_status(core); in si476x_core_interrupt()
547 static int si476x_core_fwver_to_revision(struct si476x_core *core, in si476x_core_fwver_to_revision() argument
592 dev_err(&core->client->dev, in si476x_core_fwver_to_revision()
613 static int si476x_core_get_revision_info(struct si476x_core *core) in si476x_core_get_revision_info() argument
618 si476x_core_lock(core); in si476x_core_get_revision_info()
619 rval = si476x_core_set_power_state(core, SI476X_POWER_UP_FULL); in si476x_core_get_revision_info()
623 rval = si476x_core_cmd_func_info(core, &info); in si476x_core_get_revision_info()
627 core->revision = si476x_core_fwver_to_revision(core, info.func, in si476x_core_get_revision_info()
632 si476x_core_set_power_state(core, SI476X_POWER_DOWN); in si476x_core_get_revision_info()
634 si476x_core_unlock(core); in si476x_core_get_revision_info()
639 bool si476x_core_has_am(struct si476x_core *core) in si476x_core_has_am() argument
641 return core->chip_id == SI476X_CHIP_SI4761 || in si476x_core_has_am()
642 core->chip_id == SI476X_CHIP_SI4764; in si476x_core_has_am()
646 bool si476x_core_has_diversity(struct si476x_core *core) in si476x_core_has_diversity() argument
648 return core->chip_id == SI476X_CHIP_SI4764; in si476x_core_has_diversity()
652 bool si476x_core_is_a_secondary_tuner(struct si476x_core *core) in si476x_core_is_a_secondary_tuner() argument
654 return si476x_core_has_diversity(core) && in si476x_core_is_a_secondary_tuner()
655 (core->diversity_mode == SI476X_PHDIV_SECONDARY_ANTENNA || in si476x_core_is_a_secondary_tuner()
656 core->diversity_mode == SI476X_PHDIV_SECONDARY_COMBINING); in si476x_core_is_a_secondary_tuner()
660 bool si476x_core_is_a_primary_tuner(struct si476x_core *core) in si476x_core_is_a_primary_tuner() argument
662 return si476x_core_has_diversity(core) && in si476x_core_is_a_primary_tuner()
663 (core->diversity_mode == SI476X_PHDIV_PRIMARY_ANTENNA || in si476x_core_is_a_primary_tuner()
664 core->diversity_mode == SI476X_PHDIV_PRIMARY_COMBINING); in si476x_core_is_a_primary_tuner()
668 bool si476x_core_is_in_am_receiver_mode(struct si476x_core *core) in si476x_core_is_in_am_receiver_mode() argument
670 return si476x_core_has_am(core) && in si476x_core_is_in_am_receiver_mode()
671 (core->power_up_parameters.func == SI476X_FUNC_AM_RECEIVER); in si476x_core_is_in_am_receiver_mode()
675 bool si476x_core_is_powered_up(struct si476x_core *core) in si476x_core_is_powered_up() argument
677 return core->power_state == SI476X_POWER_UP_FULL; in si476x_core_is_powered_up()
685 struct si476x_core *core; in si476x_core_probe() local
690 core = devm_kzalloc(&client->dev, sizeof(*core), GFP_KERNEL); in si476x_core_probe()
691 if (!core) in si476x_core_probe()
694 core->client = client; in si476x_core_probe()
696 core->regmap = devm_regmap_init_si476x(core); in si476x_core_probe()
697 if (IS_ERR(core->regmap)) { in si476x_core_probe()
698 rval = PTR_ERR(core->regmap); in si476x_core_probe()
705 i2c_set_clientdata(client, core); in si476x_core_probe()
707 atomic_set(&core->is_alive, 0); in si476x_core_probe()
708 core->power_state = SI476X_POWER_DOWN; in si476x_core_probe()
712 memcpy(&core->power_up_parameters, in si476x_core_probe()
714 sizeof(core->power_up_parameters)); in si476x_core_probe()
716 core->gpio_reset = -1; in si476x_core_probe()
724 core->gpio_reset = pdata->gpio_reset; in si476x_core_probe()
725 gpio_direction_output(core->gpio_reset, 0); in si476x_core_probe()
728 core->diversity_mode = pdata->diversity_mode; in si476x_core_probe()
729 memcpy(&core->pinmux, &pdata->pinmux, in si476x_core_probe()
736 core->supplies[0].supply = "vd"; in si476x_core_probe()
737 core->supplies[1].supply = "va"; in si476x_core_probe()
738 core->supplies[2].supply = "vio1"; in si476x_core_probe()
739 core->supplies[3].supply = "vio2"; in si476x_core_probe()
742 ARRAY_SIZE(core->supplies), in si476x_core_probe()
743 core->supplies); in si476x_core_probe()
749 mutex_init(&core->cmd_lock); in si476x_core_probe()
750 init_waitqueue_head(&core->command); in si476x_core_probe()
751 init_waitqueue_head(&core->tuning); in si476x_core_probe()
753 rval = kfifo_alloc(&core->rds_fifo, in si476x_core_probe()
761 mutex_init(&core->rds_drainer_status_lock); in si476x_core_probe()
762 init_waitqueue_head(&core->rds_read_queue); in si476x_core_probe()
763 INIT_WORK(&core->rds_fifo_drainer, si476x_core_drain_rds_fifo); in si476x_core_probe()
771 client->name, core); in si476x_core_probe()
780 core->rds_fifo_depth = 20; in si476x_core_probe()
782 INIT_DELAYED_WORK(&core->status_monitor, in si476x_core_probe()
787 core->rds_fifo_depth = 5; in si476x_core_probe()
790 core->chip_id = id->driver_data; in si476x_core_probe()
792 rval = si476x_core_get_revision_info(core); in si476x_core_probe()
800 cell = &core->cells[SI476X_RADIO_CELL]; in si476x_core_probe()
805 if ((core->chip_id == SI476X_CHIP_SI4761 || in si476x_core_probe()
806 core->chip_id == SI476X_CHIP_SI4764) && in si476x_core_probe()
807 core->pinmux.dclk == SI476X_DCLK_DAUDIO && in si476x_core_probe()
808 core->pinmux.dfs == SI476X_DFS_DAUDIO && in si476x_core_probe()
809 core->pinmux.dout == SI476X_DOUT_I2S_OUTPUT && in si476x_core_probe()
810 core->pinmux.xout == SI476X_XOUT_TRISTATE) { in si476x_core_probe()
811 cell = &core->cells[SI476X_CODEC_CELL]; in si476x_core_probe()
818 core->cells, cell_num, in si476x_core_probe()
824 kfifo_free(&core->rds_fifo); in si476x_core_probe()
827 if (gpio_is_valid(core->gpio_reset)) in si476x_core_probe()
828 gpio_free(core->gpio_reset); in si476x_core_probe()
835 struct si476x_core *core = i2c_get_clientdata(client); in si476x_core_remove() local
837 si476x_core_pronounce_dead(core); in si476x_core_remove()
843 cancel_delayed_work_sync(&core->status_monitor); in si476x_core_remove()
845 kfifo_free(&core->rds_fifo); in si476x_core_remove()
847 if (gpio_is_valid(core->gpio_reset)) in si476x_core_remove()
848 gpio_free(core->gpio_reset); in si476x_core_remove()