static int si476x_core_probe()

in si476x-i2c.c [686:836]


static int si476x_core_probe(struct i2c_client *client,
			     const struct i2c_device_id *id)
{
	int rval;
	struct si476x_core          *core;
	struct si476x_platform_data *pdata;
	struct mfd_cell *cell;
	int              cell_num;

	core = devm_kzalloc(&client->dev, sizeof(*core), GFP_KERNEL);
	if (!core)
		return -ENOMEM;

	core->client = client;

	core->regmap = devm_regmap_init_si476x(core);
	if (IS_ERR(core->regmap)) {
		rval = PTR_ERR(core->regmap);
		dev_err(&client->dev,
			"Failed to allocate register map: %d\n",
			rval);
		return rval;
	}

	i2c_set_clientdata(client, core);

	atomic_set(&core->is_alive, 0);
	core->power_state = SI476X_POWER_DOWN;

	pdata = dev_get_platdata(&client->dev);
	if (pdata) {
		memcpy(&core->power_up_parameters,
		       &pdata->power_up_parameters,
		       sizeof(core->power_up_parameters));

		core->gpio_reset = -1;
		if (gpio_is_valid(pdata->gpio_reset)) {
			rval = gpio_request(pdata->gpio_reset, "si476x reset");
			if (rval) {
				dev_err(&client->dev,
					"Failed to request gpio: %d\n", rval);
				return rval;
			}
			core->gpio_reset = pdata->gpio_reset;
			gpio_direction_output(core->gpio_reset, 0);
		}

		core->diversity_mode = pdata->diversity_mode;
		memcpy(&core->pinmux, &pdata->pinmux,
		       sizeof(struct si476x_pinmux));
	} else {
		dev_err(&client->dev, "No platform data provided\n");
		return -EINVAL;
	}

	core->supplies[0].supply = "vd";
	core->supplies[1].supply = "va";
	core->supplies[2].supply = "vio1";
	core->supplies[3].supply = "vio2";

	rval = devm_regulator_bulk_get(&client->dev,
				       ARRAY_SIZE(core->supplies),
				       core->supplies);
	if (rval) {
		dev_err(&client->dev, "Failed to get all of the regulators\n");
		goto free_gpio;
	}

	mutex_init(&core->cmd_lock);
	init_waitqueue_head(&core->command);
	init_waitqueue_head(&core->tuning);

	rval = kfifo_alloc(&core->rds_fifo,
			   SI476X_DRIVER_RDS_FIFO_DEPTH *
			   sizeof(struct v4l2_rds_data),
			   GFP_KERNEL);
	if (rval) {
		dev_err(&client->dev, "Could not allocate the FIFO\n");
		goto free_gpio;
	}
	mutex_init(&core->rds_drainer_status_lock);
	init_waitqueue_head(&core->rds_read_queue);
	INIT_WORK(&core->rds_fifo_drainer, si476x_core_drain_rds_fifo);

	if (client->irq) {
		rval = devm_request_threaded_irq(&client->dev,
						 client->irq, NULL,
						 si476x_core_interrupt,
						 IRQF_TRIGGER_FALLING |
						 IRQF_ONESHOT,
						 client->name, core);
		if (rval < 0) {
			dev_err(&client->dev, "Could not request IRQ %d\n",
				client->irq);
			goto free_kfifo;
		}
		disable_irq(client->irq);
		dev_dbg(&client->dev, "IRQ requested.\n");

		core->rds_fifo_depth = 20;
	} else {
		INIT_DELAYED_WORK(&core->status_monitor,
				  si476x_core_poll_loop);
		dev_info(&client->dev,
			 "No IRQ number specified, will use polling\n");

		core->rds_fifo_depth = 5;
	}

	core->chip_id = id->driver_data;

	rval = si476x_core_get_revision_info(core);
	if (rval < 0) {
		rval = -ENODEV;
		goto free_kfifo;
	}

	cell_num = 0;

	cell = &core->cells[SI476X_RADIO_CELL];
	cell->name = "si476x-radio";
	cell_num++;

#ifdef CONFIG_SND_SOC_SI476X
	if ((core->chip_id == SI476X_CHIP_SI4761 ||
	     core->chip_id == SI476X_CHIP_SI4764)	&&
	    core->pinmux.dclk == SI476X_DCLK_DAUDIO     &&
	    core->pinmux.dfs  == SI476X_DFS_DAUDIO      &&
	    core->pinmux.dout == SI476X_DOUT_I2S_OUTPUT &&
	    core->pinmux.xout == SI476X_XOUT_TRISTATE) {
		cell = &core->cells[SI476X_CODEC_CELL];
		cell->name          = "si476x-codec";
		cell_num++;
	}
#endif
	rval = mfd_add_devices(&client->dev,
			       (client->adapter->nr << 8) + client->addr,
			       core->cells, cell_num,
			       NULL, 0, NULL);
	if (!rval)
		return 0;

free_kfifo:
	kfifo_free(&core->rds_fifo);

free_gpio:
	if (gpio_is_valid(core->gpio_reset))
		gpio_free(core->gpio_reset);

	return rval;
}