diff options
-rw-r--r-- | arch/arm/mach-pxa/pcm990-baseboard.c | 23 | ||||
-rw-r--r-- | drivers/media/video/mt9m001.c | 3 | ||||
-rw-r--r-- | drivers/media/video/mt9v022.c | 3 | ||||
-rw-r--r-- | include/media/soc_camera.h | 1 |
4 files changed, 23 insertions, 7 deletions
diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c index 095521e9ee24..01791d74e08e 100644 --- a/arch/arm/mach-pxa/pcm990-baseboard.c +++ b/arch/arm/mach-pxa/pcm990-baseboard.c | |||
@@ -380,12 +380,12 @@ static struct pca953x_platform_data pca9536_data = { | |||
380 | .gpio_base = NR_BUILTIN_GPIO, | 380 | .gpio_base = NR_BUILTIN_GPIO, |
381 | }; | 381 | }; |
382 | 382 | ||
383 | static int gpio_bus_switch; | 383 | static int gpio_bus_switch = -EINVAL; |
384 | 384 | ||
385 | static int pcm990_camera_set_bus_param(struct soc_camera_link *link, | 385 | static int pcm990_camera_set_bus_param(struct soc_camera_link *link, |
386 | unsigned long flags) | 386 | unsigned long flags) |
387 | { | 387 | { |
388 | if (gpio_bus_switch <= 0) { | 388 | if (gpio_bus_switch < 0) { |
389 | if (flags == SOCAM_DATAWIDTH_10) | 389 | if (flags == SOCAM_DATAWIDTH_10) |
390 | return 0; | 390 | return 0; |
391 | else | 391 | else |
@@ -404,25 +404,34 @@ static unsigned long pcm990_camera_query_bus_param(struct soc_camera_link *link) | |||
404 | { | 404 | { |
405 | int ret; | 405 | int ret; |
406 | 406 | ||
407 | if (!gpio_bus_switch) { | 407 | if (gpio_bus_switch < 0) { |
408 | ret = gpio_request(NR_BUILTIN_GPIO, "camera"); | 408 | ret = gpio_request(NR_BUILTIN_GPIO, "camera"); |
409 | if (!ret) { | 409 | if (!ret) { |
410 | gpio_bus_switch = NR_BUILTIN_GPIO; | 410 | gpio_bus_switch = NR_BUILTIN_GPIO; |
411 | gpio_direction_output(gpio_bus_switch, 0); | 411 | gpio_direction_output(gpio_bus_switch, 0); |
412 | } else | 412 | } |
413 | gpio_bus_switch = -EINVAL; | ||
414 | } | 413 | } |
415 | 414 | ||
416 | if (gpio_bus_switch > 0) | 415 | if (gpio_bus_switch >= 0) |
417 | return SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_10; | 416 | return SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_10; |
418 | else | 417 | else |
419 | return SOCAM_DATAWIDTH_10; | 418 | return SOCAM_DATAWIDTH_10; |
420 | } | 419 | } |
421 | 420 | ||
421 | static void pcm990_camera_free_bus(struct soc_camera_link *link) | ||
422 | { | ||
423 | if (gpio_bus_switch < 0) | ||
424 | return; | ||
425 | |||
426 | gpio_free(gpio_bus_switch); | ||
427 | gpio_bus_switch = -EINVAL; | ||
428 | } | ||
429 | |||
422 | static struct soc_camera_link iclink = { | 430 | static struct soc_camera_link iclink = { |
423 | .bus_id = 0, /* Must match with the camera ID above */ | 431 | .bus_id = 0, /* Must match with the camera ID above */ |
424 | .query_bus_param = pcm990_camera_query_bus_param, | 432 | .query_bus_param = pcm990_camera_query_bus_param, |
425 | .set_bus_param = pcm990_camera_set_bus_param, | 433 | .set_bus_param = pcm990_camera_set_bus_param, |
434 | .free_bus = pcm990_camera_free_bus, | ||
426 | }; | 435 | }; |
427 | 436 | ||
428 | /* Board I2C devices. */ | 437 | /* Board I2C devices. */ |
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c index 684f62fa7897..3838ff77381b 100644 --- a/drivers/media/video/mt9m001.c +++ b/drivers/media/video/mt9m001.c | |||
@@ -604,10 +604,13 @@ ei2c: | |||
604 | static void mt9m001_video_remove(struct soc_camera_device *icd) | 604 | static void mt9m001_video_remove(struct soc_camera_device *icd) |
605 | { | 605 | { |
606 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); | 606 | struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); |
607 | struct soc_camera_link *icl = mt9m001->client->dev.platform_data; | ||
607 | 608 | ||
608 | dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m001->client->addr, | 609 | dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m001->client->addr, |
609 | icd->dev.parent, icd->vdev); | 610 | icd->dev.parent, icd->vdev); |
610 | soc_camera_video_stop(icd); | 611 | soc_camera_video_stop(icd); |
612 | if (icl->free_bus) | ||
613 | icl->free_bus(icl); | ||
611 | } | 614 | } |
612 | 615 | ||
613 | static int mt9m001_probe(struct i2c_client *client, | 616 | static int mt9m001_probe(struct i2c_client *client, |
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c index 4d3b4813c322..412b399baca4 100644 --- a/drivers/media/video/mt9v022.c +++ b/drivers/media/video/mt9v022.c | |||
@@ -735,10 +735,13 @@ ei2c: | |||
735 | static void mt9v022_video_remove(struct soc_camera_device *icd) | 735 | static void mt9v022_video_remove(struct soc_camera_device *icd) |
736 | { | 736 | { |
737 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); | 737 | struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); |
738 | struct soc_camera_link *icl = mt9v022->client->dev.platform_data; | ||
738 | 739 | ||
739 | dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9v022->client->addr, | 740 | dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9v022->client->addr, |
740 | icd->dev.parent, icd->vdev); | 741 | icd->dev.parent, icd->vdev); |
741 | soc_camera_video_stop(icd); | 742 | soc_camera_video_stop(icd); |
743 | if (icl->free_bus) | ||
744 | icl->free_bus(icl); | ||
742 | } | 745 | } |
743 | 746 | ||
744 | static int mt9v022_probe(struct i2c_client *client, | 747 | static int mt9v022_probe(struct i2c_client *client, |
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index 37013688af44..396c32550e04 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h | |||
@@ -107,6 +107,7 @@ struct soc_camera_link { | |||
107 | */ | 107 | */ |
108 | int (*set_bus_param)(struct soc_camera_link *, unsigned long flags); | 108 | int (*set_bus_param)(struct soc_camera_link *, unsigned long flags); |
109 | unsigned long (*query_bus_param)(struct soc_camera_link *); | 109 | unsigned long (*query_bus_param)(struct soc_camera_link *); |
110 | void (*free_bus)(struct soc_camera_link *); | ||
110 | }; | 111 | }; |
111 | 112 | ||
112 | static inline struct soc_camera_device *to_soc_camera_dev(struct device *dev) | 113 | static inline struct soc_camera_device *to_soc_camera_dev(struct device *dev) |