diff options
Diffstat (limited to 'drivers/media/radio/si4713-i2c.c')
-rw-r--r-- | drivers/media/radio/si4713-i2c.c | 74 |
1 files changed, 63 insertions, 11 deletions
diff --git a/drivers/media/radio/si4713-i2c.c b/drivers/media/radio/si4713-i2c.c index a6e6f1987a3a..0fab6f8f7e24 100644 --- a/drivers/media/radio/si4713-i2c.c +++ b/drivers/media/radio/si4713-i2c.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
28 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/gpio.h> | ||
31 | #include <linux/regulator/consumer.h> | ||
30 | #include <media/v4l2-device.h> | 32 | #include <media/v4l2-device.h> |
31 | #include <media/v4l2-ioctl.h> | 33 | #include <media/v4l2-ioctl.h> |
32 | #include <media/v4l2-common.h> | 34 | #include <media/v4l2-common.h> |
@@ -43,6 +45,11 @@ MODULE_AUTHOR("Eduardo Valentin <eduardo.valentin@nokia.com>"); | |||
43 | MODULE_DESCRIPTION("I2C driver for Si4713 FM Radio Transmitter"); | 45 | MODULE_DESCRIPTION("I2C driver for Si4713 FM Radio Transmitter"); |
44 | MODULE_VERSION("0.0.1"); | 46 | MODULE_VERSION("0.0.1"); |
45 | 47 | ||
48 | static const char *si4713_supply_names[SI4713_NUM_SUPPLIES] = { | ||
49 | "vio", | ||
50 | "vdd", | ||
51 | }; | ||
52 | |||
46 | #define DEFAULT_RDS_PI 0x00 | 53 | #define DEFAULT_RDS_PI 0x00 |
47 | #define DEFAULT_RDS_PTY 0x00 | 54 | #define DEFAULT_RDS_PTY 0x00 |
48 | #define DEFAULT_RDS_PS_NAME "" | 55 | #define DEFAULT_RDS_PS_NAME "" |
@@ -369,7 +376,17 @@ static int si4713_powerup(struct si4713_device *sdev) | |||
369 | if (sdev->power_state) | 376 | if (sdev->power_state) |
370 | return 0; | 377 | return 0; |
371 | 378 | ||
372 | sdev->platform_data->set_power(1); | 379 | err = regulator_bulk_enable(ARRAY_SIZE(sdev->supplies), |
380 | sdev->supplies); | ||
381 | if (err) { | ||
382 | v4l2_err(&sdev->sd, "Failed to enable supplies: %d\n", err); | ||
383 | return err; | ||
384 | } | ||
385 | if (gpio_is_valid(sdev->gpio_reset)) { | ||
386 | udelay(50); | ||
387 | gpio_set_value(sdev->gpio_reset, 1); | ||
388 | } | ||
389 | |||
373 | err = si4713_send_command(sdev, SI4713_CMD_POWER_UP, | 390 | err = si4713_send_command(sdev, SI4713_CMD_POWER_UP, |
374 | args, ARRAY_SIZE(args), | 391 | args, ARRAY_SIZE(args), |
375 | resp, ARRAY_SIZE(resp), | 392 | resp, ARRAY_SIZE(resp), |
@@ -384,7 +401,13 @@ static int si4713_powerup(struct si4713_device *sdev) | |||
384 | err = si4713_write_property(sdev, SI4713_GPO_IEN, | 401 | err = si4713_write_property(sdev, SI4713_GPO_IEN, |
385 | SI4713_STC_INT | SI4713_CTS); | 402 | SI4713_STC_INT | SI4713_CTS); |
386 | } else { | 403 | } else { |
387 | sdev->platform_data->set_power(0); | 404 | if (gpio_is_valid(sdev->gpio_reset)) |
405 | gpio_set_value(sdev->gpio_reset, 0); | ||
406 | err = regulator_bulk_disable(ARRAY_SIZE(sdev->supplies), | ||
407 | sdev->supplies); | ||
408 | if (err) | ||
409 | v4l2_err(&sdev->sd, | ||
410 | "Failed to disable supplies: %d\n", err); | ||
388 | } | 411 | } |
389 | 412 | ||
390 | return err; | 413 | return err; |
@@ -411,7 +434,13 @@ static int si4713_powerdown(struct si4713_device *sdev) | |||
411 | v4l2_dbg(1, debug, &sdev->sd, "Power down response: 0x%02x\n", | 434 | v4l2_dbg(1, debug, &sdev->sd, "Power down response: 0x%02x\n", |
412 | resp[0]); | 435 | resp[0]); |
413 | v4l2_dbg(1, debug, &sdev->sd, "Device in reset mode\n"); | 436 | v4l2_dbg(1, debug, &sdev->sd, "Device in reset mode\n"); |
414 | sdev->platform_data->set_power(0); | 437 | if (gpio_is_valid(sdev->gpio_reset)) |
438 | gpio_set_value(sdev->gpio_reset, 0); | ||
439 | err = regulator_bulk_disable(ARRAY_SIZE(sdev->supplies), | ||
440 | sdev->supplies); | ||
441 | if (err) | ||
442 | v4l2_err(&sdev->sd, | ||
443 | "Failed to disable supplies: %d\n", err); | ||
415 | sdev->power_state = POWER_OFF; | 444 | sdev->power_state = POWER_OFF; |
416 | } | 445 | } |
417 | 446 | ||
@@ -1967,7 +1996,8 @@ static int si4713_probe(struct i2c_client *client, | |||
1967 | const struct i2c_device_id *id) | 1996 | const struct i2c_device_id *id) |
1968 | { | 1997 | { |
1969 | struct si4713_device *sdev; | 1998 | struct si4713_device *sdev; |
1970 | int rval; | 1999 | struct si4713_platform_data *pdata = client->dev.platform_data; |
2000 | int rval, i; | ||
1971 | 2001 | ||
1972 | sdev = kzalloc(sizeof *sdev, GFP_KERNEL); | 2002 | sdev = kzalloc(sizeof *sdev, GFP_KERNEL); |
1973 | if (!sdev) { | 2003 | if (!sdev) { |
@@ -1976,11 +2006,26 @@ static int si4713_probe(struct i2c_client *client, | |||
1976 | goto exit; | 2006 | goto exit; |
1977 | } | 2007 | } |
1978 | 2008 | ||
1979 | sdev->platform_data = client->dev.platform_data; | 2009 | sdev->gpio_reset = -1; |
1980 | if (!sdev->platform_data) { | 2010 | if (pdata && gpio_is_valid(pdata->gpio_reset)) { |
1981 | v4l2_err(&sdev->sd, "No platform data registered.\n"); | 2011 | rval = gpio_request(pdata->gpio_reset, "si4713 reset"); |
1982 | rval = -ENODEV; | 2012 | if (rval) { |
1983 | goto free_sdev; | 2013 | dev_err(&client->dev, |
2014 | "Failed to request gpio: %d\n", rval); | ||
2015 | goto free_sdev; | ||
2016 | } | ||
2017 | sdev->gpio_reset = pdata->gpio_reset; | ||
2018 | gpio_direction_output(sdev->gpio_reset, 0); | ||
2019 | } | ||
2020 | |||
2021 | for (i = 0; i < ARRAY_SIZE(sdev->supplies); i++) | ||
2022 | sdev->supplies[i].supply = si4713_supply_names[i]; | ||
2023 | |||
2024 | rval = regulator_bulk_get(&client->dev, ARRAY_SIZE(sdev->supplies), | ||
2025 | sdev->supplies); | ||
2026 | if (rval) { | ||
2027 | dev_err(&client->dev, "Cannot get regulators: %d\n", rval); | ||
2028 | goto free_gpio; | ||
1984 | } | 2029 | } |
1985 | 2030 | ||
1986 | v4l2_i2c_subdev_init(&sdev->sd, client, &si4713_subdev_ops); | 2031 | v4l2_i2c_subdev_init(&sdev->sd, client, &si4713_subdev_ops); |
@@ -1994,7 +2039,7 @@ static int si4713_probe(struct i2c_client *client, | |||
1994 | client->name, sdev); | 2039 | client->name, sdev); |
1995 | if (rval < 0) { | 2040 | if (rval < 0) { |
1996 | v4l2_err(&sdev->sd, "Could not request IRQ\n"); | 2041 | v4l2_err(&sdev->sd, "Could not request IRQ\n"); |
1997 | goto free_sdev; | 2042 | goto put_reg; |
1998 | } | 2043 | } |
1999 | v4l2_dbg(1, debug, &sdev->sd, "IRQ requested.\n"); | 2044 | v4l2_dbg(1, debug, &sdev->sd, "IRQ requested.\n"); |
2000 | } else { | 2045 | } else { |
@@ -2012,6 +2057,11 @@ static int si4713_probe(struct i2c_client *client, | |||
2012 | free_irq: | 2057 | free_irq: |
2013 | if (client->irq) | 2058 | if (client->irq) |
2014 | free_irq(client->irq, sdev); | 2059 | free_irq(client->irq, sdev); |
2060 | put_reg: | ||
2061 | regulator_bulk_free(ARRAY_SIZE(sdev->supplies), sdev->supplies); | ||
2062 | free_gpio: | ||
2063 | if (gpio_is_valid(sdev->gpio_reset)) | ||
2064 | gpio_free(sdev->gpio_reset); | ||
2015 | free_sdev: | 2065 | free_sdev: |
2016 | kfree(sdev); | 2066 | kfree(sdev); |
2017 | exit: | 2067 | exit: |
@@ -2031,7 +2081,9 @@ static int si4713_remove(struct i2c_client *client) | |||
2031 | free_irq(client->irq, sdev); | 2081 | free_irq(client->irq, sdev); |
2032 | 2082 | ||
2033 | v4l2_device_unregister_subdev(sd); | 2083 | v4l2_device_unregister_subdev(sd); |
2034 | 2084 | regulator_bulk_free(ARRAY_SIZE(sdev->supplies), sdev->supplies); | |
2085 | if (gpio_is_valid(sdev->gpio_reset)) | ||
2086 | gpio_free(sdev->gpio_reset); | ||
2035 | kfree(sdev); | 2087 | kfree(sdev); |
2036 | 2088 | ||
2037 | return 0; | 2089 | return 0; |