Lines Matching +full:pinmux +full:- +full:id
2 * drivers/mfd/si476x-i2c.c -- Core device driver for si476x MFD
30 #include <linux/mfd/si476x-core.h>
36 * si476x_core_config_pinmux() - pin function configuration function
48 dev_dbg(&core->client->dev, "Configuring pinmux\n"); in si476x_core_config_pinmux()
50 core->pinmux.dclk, in si476x_core_config_pinmux()
51 core->pinmux.dfs, in si476x_core_config_pinmux()
52 core->pinmux.dout, in si476x_core_config_pinmux()
53 core->pinmux.xout); in si476x_core_config_pinmux()
55 dev_err(&core->client->dev, in si476x_core_config_pinmux()
62 core->pinmux.iqclk, in si476x_core_config_pinmux()
63 core->pinmux.iqfs, in si476x_core_config_pinmux()
64 core->pinmux.iout, in si476x_core_config_pinmux()
65 core->pinmux.qout); in si476x_core_config_pinmux()
67 dev_err(&core->client->dev, in si476x_core_config_pinmux()
74 core->pinmux.icin, in si476x_core_config_pinmux()
75 core->pinmux.icip, in si476x_core_config_pinmux()
76 core->pinmux.icon, in si476x_core_config_pinmux()
77 core->pinmux.icop); in si476x_core_config_pinmux()
79 dev_err(&core->client->dev, in si476x_core_config_pinmux()
80 "Failed to configure IC-Link/GPO pins(err = %d)\n", in si476x_core_config_pinmux()
86 core->pinmux.lrout); in si476x_core_config_pinmux()
88 dev_err(&core->client->dev, in si476x_core_config_pinmux()
95 core->pinmux.intb, in si476x_core_config_pinmux()
96 core->pinmux.a1); in si476x_core_config_pinmux()
98 dev_err(&core->client->dev, in si476x_core_config_pinmux()
109 schedule_delayed_work(&core->status_monitor, in si476x_core_schedule_polling_work()
114 * si476x_core_start() - early chip startup function
129 * information about power-up parameters.
138 struct i2c_client *client = core->client; in si476x_core_start()
142 if (gpio_is_valid(core->gpio_reset)) in si476x_core_start()
143 gpio_set_value_cansleep(core->gpio_reset, 1); in si476x_core_start()
145 if (client->irq) in si476x_core_start()
146 enable_irq(client->irq); in si476x_core_start()
150 if (!client->irq) { in si476x_core_start()
151 atomic_set(&core->is_alive, 1); in si476x_core_start()
155 if (client->irq) in si476x_core_start()
156 enable_irq(client->irq); in si476x_core_start()
158 atomic_set(&core->is_alive, 1); in si476x_core_start()
164 &core->power_up_parameters); in si476x_core_start()
167 dev_err(&core->client->dev, in si476x_core_start()
173 if (client->irq) in si476x_core_start()
174 atomic_set(&core->is_alive, 1); in si476x_core_start()
178 dev_err(&core->client->dev, in si476x_core_start()
179 "Failed to configure pinmux(err = %d)\n", in si476x_core_start()
184 if (client->irq) { in si476x_core_start()
185 err = regmap_write(core->regmap, in si476x_core_start()
191 dev_err(&core->client->dev, in si476x_core_start()
201 if (err == -ENODEV) in si476x_core_start()
202 atomic_set(&core->is_alive, 0); in si476x_core_start()
204 if (client->irq) in si476x_core_start()
205 disable_irq(client->irq); in si476x_core_start()
207 cancel_delayed_work_sync(&core->status_monitor); in si476x_core_start()
209 if (gpio_is_valid(core->gpio_reset)) in si476x_core_start()
210 gpio_set_value_cansleep(core->gpio_reset, 0); in si476x_core_start()
217 * si476x_core_stop() - chip power-down function
233 atomic_set(&core->is_alive, 0); in si476x_core_stop()
249 if (core->client->irq) in si476x_core_stop()
250 disable_irq(core->client->irq); in si476x_core_stop()
252 cancel_delayed_work_sync(&core->status_monitor); in si476x_core_stop()
255 if (gpio_is_valid(core->gpio_reset)) in si476x_core_stop()
256 gpio_set_value_cansleep(core->gpio_reset, 0); in si476x_core_stop()
263 * si476x_core_set_power_state() - set the level at which the power is
280 So for now the power-up policy is "power-up all the things!" in si476x_core_set_power_state()
284 if (core->power_state == SI476X_POWER_INCONSISTENT) { in si476x_core_set_power_state()
285 dev_err(&core->client->dev, in si476x_core_set_power_state()
287 return -EINVAL; in si476x_core_set_power_state()
290 if (next_state != core->power_state) { in si476x_core_set_power_state()
293 err = regulator_bulk_enable(ARRAY_SIZE(core->supplies), in si476x_core_set_power_state()
294 core->supplies); in si476x_core_set_power_state()
296 core->power_state = SI476X_POWER_INCONSISTENT; in si476x_core_set_power_state()
310 core->power_state = next_state; in si476x_core_set_power_state()
314 core->power_state = next_state; in si476x_core_set_power_state()
317 core->power_state = SI476X_POWER_INCONSISTENT; in si476x_core_set_power_state()
319 err = regulator_bulk_disable(ARRAY_SIZE(core->supplies), in si476x_core_set_power_state()
320 core->supplies); in si476x_core_set_power_state()
322 core->power_state = SI476X_POWER_INCONSISTENT; in si476x_core_set_power_state()
334 * si476x_core_report_drainer_stop() - mark the completion of the RDS
341 mutex_lock(&core->rds_drainer_status_lock); in si476x_core_report_drainer_stop()
342 core->rds_drainer_is_working = false; in si476x_core_report_drainer_stop()
343 mutex_unlock(&core->rds_drainer_status_lock); in si476x_core_report_drainer_stop()
347 * si476x_core_start_rds_drainer_once() - start RDS drainer worker if
354 mutex_lock(&core->rds_drainer_status_lock); in si476x_core_start_rds_drainer_once()
355 if (!core->rds_drainer_is_working) { in si476x_core_start_rds_drainer_once()
356 core->rds_drainer_is_working = true; in si476x_core_start_rds_drainer_once()
357 schedule_work(&core->rds_fifo_drainer); in si476x_core_start_rds_drainer_once()
359 mutex_unlock(&core->rds_drainer_status_lock); in si476x_core_start_rds_drainer_once()
362 * si476x_drain_rds_fifo() - RDS buffer drainer.
381 dev_dbg(&core->client->dev, in si476x_core_drain_rds_fifo()
383 for (; i > 0; --i) { in si476x_core_drain_rds_fifo()
389 kfifo_in(&core->rds_fifo, report.rds, in si476x_core_drain_rds_fifo()
391 dev_dbg(&core->client->dev, "RDS data:\n %*ph\n", in si476x_core_drain_rds_fifo()
394 dev_dbg(&core->client->dev, "Drrrrained!\n"); in si476x_core_drain_rds_fifo()
395 wake_up_interruptible(&core->rds_read_queue); in si476x_core_drain_rds_fifo()
414 dev_info(&core->client->dev, "Core device is dead.\n"); in si476x_core_pronounce_dead()
416 atomic_set(&core->is_alive, 0); in si476x_core_pronounce_dead()
419 wake_up_interruptible(&core->rds_read_queue); in si476x_core_pronounce_dead()
421 atomic_set(&core->cts, 1); in si476x_core_pronounce_dead()
422 wake_up(&core->command); in si476x_core_pronounce_dead()
424 atomic_set(&core->stc, 1); in si476x_core_pronounce_dead()
425 wake_up(&core->tuning); in si476x_core_pronounce_dead()
450 err = i2c_master_send(core->client, buf, count); in si476x_core_i2c_xfer()
452 err = i2c_master_recv(core->client, buf, count); in si476x_core_i2c_xfer()
485 * si476x_get_and_signal_status() - IRQ dispatcher
496 dev_err(&core->client->dev, "Failed to get status\n"); in si476x_core_get_and_signal_status()
507 dev_dbg(&core->client->dev, "[interrupt] CTSINT\n"); in si476x_core_get_and_signal_status()
508 atomic_set(&core->cts, 1); in si476x_core_get_and_signal_status()
509 wake_up(&core->command); in si476x_core_get_and_signal_status()
513 dev_dbg(&core->client->dev, "[interrupt] RDSINT\n"); in si476x_core_get_and_signal_status()
518 dev_dbg(&core->client->dev, "[interrupt] STCINT\n"); in si476x_core_get_and_signal_status()
519 atomic_set(&core->stc, 1); in si476x_core_get_and_signal_status()
520 wake_up(&core->tuning); in si476x_core_get_and_signal_status()
530 if (atomic_read(&core->is_alive)) in si476x_core_poll_loop()
553 * This function returns a positive offset in case of success and a -1
597 return -1; in si476x_core_fwver_to_revision()
601 dev_err(&core->client->dev, in si476x_core_fwver_to_revision()
615 * 1. Power-up the device
636 core->revision = si476x_core_fwver_to_revision(core, info.func, in si476x_core_get_revision_info()
650 return core->chip_id == SI476X_CHIP_SI4761 || in si476x_core_has_am()
651 core->chip_id == SI476X_CHIP_SI4764; in si476x_core_has_am()
657 return core->chip_id == SI476X_CHIP_SI4764; in si476x_core_has_diversity()
664 (core->diversity_mode == SI476X_PHDIV_SECONDARY_ANTENNA || in si476x_core_is_a_secondary_tuner()
665 core->diversity_mode == SI476X_PHDIV_SECONDARY_COMBINING); in si476x_core_is_a_secondary_tuner()
672 (core->diversity_mode == SI476X_PHDIV_PRIMARY_ANTENNA || in si476x_core_is_a_primary_tuner()
673 core->diversity_mode == SI476X_PHDIV_PRIMARY_COMBINING); in si476x_core_is_a_primary_tuner()
680 (core->power_up_parameters.func == SI476X_FUNC_AM_RECEIVER); in si476x_core_is_in_am_receiver_mode()
686 return core->power_state == SI476X_POWER_UP_FULL; in si476x_core_is_powered_up()
691 const struct i2c_device_id *id) in si476x_core_probe() argument
699 core = devm_kzalloc(&client->dev, sizeof(*core), GFP_KERNEL); in si476x_core_probe()
701 return -ENOMEM; in si476x_core_probe()
703 core->client = client; in si476x_core_probe()
705 core->regmap = devm_regmap_init_si476x(core); in si476x_core_probe()
706 if (IS_ERR(core->regmap)) { in si476x_core_probe()
707 rval = PTR_ERR(core->regmap); in si476x_core_probe()
708 dev_err(&client->dev, in si476x_core_probe()
716 atomic_set(&core->is_alive, 0); in si476x_core_probe()
717 core->power_state = SI476X_POWER_DOWN; in si476x_core_probe()
719 pdata = dev_get_platdata(&client->dev); in si476x_core_probe()
721 memcpy(&core->power_up_parameters, in si476x_core_probe()
722 &pdata->power_up_parameters, in si476x_core_probe()
723 sizeof(core->power_up_parameters)); in si476x_core_probe()
725 core->gpio_reset = -1; in si476x_core_probe()
726 if (gpio_is_valid(pdata->gpio_reset)) { in si476x_core_probe()
727 rval = gpio_request(pdata->gpio_reset, "si476x reset"); in si476x_core_probe()
729 dev_err(&client->dev, in si476x_core_probe()
733 core->gpio_reset = pdata->gpio_reset; in si476x_core_probe()
734 gpio_direction_output(core->gpio_reset, 0); in si476x_core_probe()
737 core->diversity_mode = pdata->diversity_mode; in si476x_core_probe()
738 memcpy(&core->pinmux, &pdata->pinmux, in si476x_core_probe()
741 dev_err(&client->dev, "No platform data provided\n"); in si476x_core_probe()
742 return -EINVAL; in si476x_core_probe()
745 core->supplies[0].supply = "vd"; in si476x_core_probe()
746 core->supplies[1].supply = "va"; in si476x_core_probe()
747 core->supplies[2].supply = "vio1"; in si476x_core_probe()
748 core->supplies[3].supply = "vio2"; in si476x_core_probe()
750 rval = devm_regulator_bulk_get(&client->dev, in si476x_core_probe()
751 ARRAY_SIZE(core->supplies), in si476x_core_probe()
752 core->supplies); in si476x_core_probe()
754 dev_err(&client->dev, "Failed to get all of the regulators\n"); in si476x_core_probe()
758 mutex_init(&core->cmd_lock); in si476x_core_probe()
759 init_waitqueue_head(&core->command); in si476x_core_probe()
760 init_waitqueue_head(&core->tuning); in si476x_core_probe()
762 rval = kfifo_alloc(&core->rds_fifo, in si476x_core_probe()
767 dev_err(&client->dev, "Could not allocate the FIFO\n"); in si476x_core_probe()
770 mutex_init(&core->rds_drainer_status_lock); in si476x_core_probe()
771 init_waitqueue_head(&core->rds_read_queue); in si476x_core_probe()
772 INIT_WORK(&core->rds_fifo_drainer, si476x_core_drain_rds_fifo); in si476x_core_probe()
774 if (client->irq) { in si476x_core_probe()
775 rval = devm_request_threaded_irq(&client->dev, in si476x_core_probe()
776 client->irq, NULL, in si476x_core_probe()
780 client->name, core); in si476x_core_probe()
782 dev_err(&client->dev, "Could not request IRQ %d\n", in si476x_core_probe()
783 client->irq); in si476x_core_probe()
786 disable_irq(client->irq); in si476x_core_probe()
787 dev_dbg(&client->dev, "IRQ requested.\n"); in si476x_core_probe()
789 core->rds_fifo_depth = 20; in si476x_core_probe()
791 INIT_DELAYED_WORK(&core->status_monitor, in si476x_core_probe()
793 dev_info(&client->dev, in si476x_core_probe()
796 core->rds_fifo_depth = 5; in si476x_core_probe()
799 core->chip_id = id->driver_data; in si476x_core_probe()
803 rval = -ENODEV; in si476x_core_probe()
809 cell = &core->cells[SI476X_RADIO_CELL]; in si476x_core_probe()
810 cell->name = "si476x-radio"; in si476x_core_probe()
814 if ((core->chip_id == SI476X_CHIP_SI4761 || in si476x_core_probe()
815 core->chip_id == SI476X_CHIP_SI4764) && in si476x_core_probe()
816 core->pinmux.dclk == SI476X_DCLK_DAUDIO && in si476x_core_probe()
817 core->pinmux.dfs == SI476X_DFS_DAUDIO && in si476x_core_probe()
818 core->pinmux.dout == SI476X_DOUT_I2S_OUTPUT && in si476x_core_probe()
819 core->pinmux.xout == SI476X_XOUT_TRISTATE) { in si476x_core_probe()
820 cell = &core->cells[SI476X_CODEC_CELL]; in si476x_core_probe()
821 cell->name = "si476x-codec"; in si476x_core_probe()
825 rval = mfd_add_devices(&client->dev, in si476x_core_probe()
826 (client->adapter->nr << 8) + client->addr, in si476x_core_probe()
827 core->cells, cell_num, in si476x_core_probe()
833 kfifo_free(&core->rds_fifo); in si476x_core_probe()
836 if (gpio_is_valid(core->gpio_reset)) in si476x_core_probe()
837 gpio_free(core->gpio_reset); in si476x_core_probe()
847 mfd_remove_devices(&client->dev); in si476x_core_remove()
849 if (client->irq) in si476x_core_remove()
850 disable_irq(client->irq); in si476x_core_remove()
852 cancel_delayed_work_sync(&core->status_monitor); in si476x_core_remove()
854 kfifo_free(&core->rds_fifo); in si476x_core_remove()
856 if (gpio_is_valid(core->gpio_reset)) in si476x_core_remove()
857 gpio_free(core->gpio_reset); in si476x_core_remove()
873 .name = "si476x-core",