diff options
-rw-r--r-- | drivers/media/platform/davinci/vpif_capture.c | 151 | ||||
-rw-r--r-- | drivers/media/platform/davinci/vpif_capture.h | 2 | ||||
-rw-r--r-- | include/media/davinci/vpif_types.h | 2 |
3 files changed, 107 insertions, 48 deletions
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index 5514175bbd07..b11d7a74497e 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c | |||
@@ -1979,6 +1979,76 @@ vpif_init_free_channel_objects: | |||
1979 | return err; | 1979 | return err; |
1980 | } | 1980 | } |
1981 | 1981 | ||
1982 | static int vpif_async_bound(struct v4l2_async_notifier *notifier, | ||
1983 | struct v4l2_subdev *subdev, | ||
1984 | struct v4l2_async_subdev *asd) | ||
1985 | { | ||
1986 | int i; | ||
1987 | |||
1988 | for (i = 0; i < vpif_obj.config->subdev_count; i++) | ||
1989 | if (!strcmp(vpif_obj.config->subdev_info[i].name, | ||
1990 | subdev->name)) { | ||
1991 | vpif_obj.sd[i] = subdev; | ||
1992 | return 0; | ||
1993 | } | ||
1994 | |||
1995 | return -EINVAL; | ||
1996 | } | ||
1997 | |||
1998 | static int vpif_probe_complete(void) | ||
1999 | { | ||
2000 | struct common_obj *common; | ||
2001 | struct channel_obj *ch; | ||
2002 | int i, j, err, k; | ||
2003 | |||
2004 | for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) { | ||
2005 | ch = vpif_obj.dev[j]; | ||
2006 | ch->channel_id = j; | ||
2007 | common = &(ch->common[VPIF_VIDEO_INDEX]); | ||
2008 | spin_lock_init(&common->irqlock); | ||
2009 | mutex_init(&common->lock); | ||
2010 | ch->video_dev->lock = &common->lock; | ||
2011 | /* Initialize prio member of channel object */ | ||
2012 | v4l2_prio_init(&ch->prio); | ||
2013 | video_set_drvdata(ch->video_dev, ch); | ||
2014 | |||
2015 | /* select input 0 */ | ||
2016 | err = vpif_set_input(vpif_obj.config, ch, 0); | ||
2017 | if (err) | ||
2018 | goto probe_out; | ||
2019 | |||
2020 | err = video_register_device(ch->video_dev, | ||
2021 | VFL_TYPE_GRABBER, (j ? 1 : 0)); | ||
2022 | if (err) | ||
2023 | goto probe_out; | ||
2024 | } | ||
2025 | |||
2026 | v4l2_info(&vpif_obj.v4l2_dev, "VPIF capture driver initialized\n"); | ||
2027 | return 0; | ||
2028 | |||
2029 | probe_out: | ||
2030 | for (k = 0; k < j; k++) { | ||
2031 | /* Get the pointer to the channel object */ | ||
2032 | ch = vpif_obj.dev[k]; | ||
2033 | /* Unregister video device */ | ||
2034 | video_unregister_device(ch->video_dev); | ||
2035 | } | ||
2036 | kfree(vpif_obj.sd); | ||
2037 | for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) { | ||
2038 | ch = vpif_obj.dev[i]; | ||
2039 | /* Note: does nothing if ch->video_dev == NULL */ | ||
2040 | video_device_release(ch->video_dev); | ||
2041 | } | ||
2042 | v4l2_device_unregister(&vpif_obj.v4l2_dev); | ||
2043 | |||
2044 | return err; | ||
2045 | } | ||
2046 | |||
2047 | static int vpif_async_complete(struct v4l2_async_notifier *notifier) | ||
2048 | { | ||
2049 | return vpif_probe_complete(); | ||
2050 | } | ||
2051 | |||
1982 | /** | 2052 | /** |
1983 | * vpif_probe : This function probes the vpif capture driver | 2053 | * vpif_probe : This function probes the vpif capture driver |
1984 | * @pdev: platform device pointer | 2054 | * @pdev: platform device pointer |
@@ -1989,12 +2059,10 @@ vpif_init_free_channel_objects: | |||
1989 | static __init int vpif_probe(struct platform_device *pdev) | 2059 | static __init int vpif_probe(struct platform_device *pdev) |
1990 | { | 2060 | { |
1991 | struct vpif_subdev_info *subdevdata; | 2061 | struct vpif_subdev_info *subdevdata; |
1992 | struct vpif_capture_config *config; | 2062 | int i, j, err; |
1993 | int i, j, k, err; | ||
1994 | int res_idx = 0; | 2063 | int res_idx = 0; |
1995 | struct i2c_adapter *i2c_adap; | 2064 | struct i2c_adapter *i2c_adap; |
1996 | struct channel_obj *ch; | 2065 | struct channel_obj *ch; |
1997 | struct common_obj *common; | ||
1998 | struct video_device *vfd; | 2066 | struct video_device *vfd; |
1999 | struct resource *res; | 2067 | struct resource *res; |
2000 | int subdev_count; | 2068 | int subdev_count; |
@@ -2068,10 +2136,9 @@ static __init int vpif_probe(struct platform_device *pdev) | |||
2068 | } | 2136 | } |
2069 | } | 2137 | } |
2070 | 2138 | ||
2071 | i2c_adap = i2c_get_adapter(1); | 2139 | vpif_obj.config = pdev->dev.platform_data; |
2072 | config = pdev->dev.platform_data; | ||
2073 | 2140 | ||
2074 | subdev_count = config->subdev_count; | 2141 | subdev_count = vpif_obj.config->subdev_count; |
2075 | vpif_obj.sd = kzalloc(sizeof(struct v4l2_subdev *) * subdev_count, | 2142 | vpif_obj.sd = kzalloc(sizeof(struct v4l2_subdev *) * subdev_count, |
2076 | GFP_KERNEL); | 2143 | GFP_KERNEL); |
2077 | if (vpif_obj.sd == NULL) { | 2144 | if (vpif_obj.sd == NULL) { |
@@ -2080,54 +2147,42 @@ static __init int vpif_probe(struct platform_device *pdev) | |||
2080 | goto vpif_sd_error; | 2147 | goto vpif_sd_error; |
2081 | } | 2148 | } |
2082 | 2149 | ||
2083 | for (i = 0; i < subdev_count; i++) { | 2150 | if (!vpif_obj.config->asd_sizes) { |
2084 | subdevdata = &config->subdev_info[i]; | 2151 | i2c_adap = i2c_get_adapter(1); |
2085 | vpif_obj.sd[i] = | 2152 | for (i = 0; i < subdev_count; i++) { |
2086 | v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev, | 2153 | subdevdata = &vpif_obj.config->subdev_info[i]; |
2087 | i2c_adap, | 2154 | vpif_obj.sd[i] = |
2088 | &subdevdata->board_info, | 2155 | v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev, |
2089 | NULL); | 2156 | i2c_adap, |
2090 | 2157 | &subdevdata-> | |
2091 | if (!vpif_obj.sd[i]) { | 2158 | board_info, |
2092 | vpif_err("Error registering v4l2 subdevice\n"); | 2159 | NULL); |
2093 | err = -ENODEV; | 2160 | |
2161 | if (!vpif_obj.sd[i]) { | ||
2162 | vpif_err("Error registering v4l2 subdevice\n"); | ||
2163 | goto probe_subdev_out; | ||
2164 | } | ||
2165 | v4l2_info(&vpif_obj.v4l2_dev, | ||
2166 | "registered sub device %s\n", | ||
2167 | subdevdata->name); | ||
2168 | } | ||
2169 | vpif_probe_complete(); | ||
2170 | } else { | ||
2171 | vpif_obj.notifier.subdev = vpif_obj.config->asd; | ||
2172 | vpif_obj.notifier.num_subdevs = vpif_obj.config->asd_sizes[0]; | ||
2173 | vpif_obj.notifier.bound = vpif_async_bound; | ||
2174 | vpif_obj.notifier.complete = vpif_async_complete; | ||
2175 | err = v4l2_async_notifier_register(&vpif_obj.v4l2_dev, | ||
2176 | &vpif_obj.notifier); | ||
2177 | if (err) { | ||
2178 | vpif_err("Error registering async notifier\n"); | ||
2179 | err = -EINVAL; | ||
2094 | goto probe_subdev_out; | 2180 | goto probe_subdev_out; |
2095 | } | 2181 | } |
2096 | v4l2_info(&vpif_obj.v4l2_dev, "registered sub device %s\n", | ||
2097 | subdevdata->name); | ||
2098 | } | 2182 | } |
2099 | 2183 | ||
2100 | for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) { | ||
2101 | ch = vpif_obj.dev[j]; | ||
2102 | ch->channel_id = j; | ||
2103 | common = &(ch->common[VPIF_VIDEO_INDEX]); | ||
2104 | spin_lock_init(&common->irqlock); | ||
2105 | mutex_init(&common->lock); | ||
2106 | ch->video_dev->lock = &common->lock; | ||
2107 | /* Initialize prio member of channel object */ | ||
2108 | v4l2_prio_init(&ch->prio); | ||
2109 | video_set_drvdata(ch->video_dev, ch); | ||
2110 | |||
2111 | /* select input 0 */ | ||
2112 | err = vpif_set_input(config, ch, 0); | ||
2113 | if (err) | ||
2114 | goto probe_out; | ||
2115 | |||
2116 | err = video_register_device(ch->video_dev, | ||
2117 | VFL_TYPE_GRABBER, (j ? 1 : 0)); | ||
2118 | if (err) | ||
2119 | goto probe_out; | ||
2120 | } | ||
2121 | v4l2_info(&vpif_obj.v4l2_dev, "VPIF capture driver initialized\n"); | ||
2122 | return 0; | 2184 | return 0; |
2123 | 2185 | ||
2124 | probe_out: | ||
2125 | for (k = 0; k < j; k++) { | ||
2126 | /* Get the pointer to the channel object */ | ||
2127 | ch = vpif_obj.dev[k]; | ||
2128 | /* Unregister video device */ | ||
2129 | video_unregister_device(ch->video_dev); | ||
2130 | } | ||
2131 | probe_subdev_out: | 2186 | probe_subdev_out: |
2132 | /* free sub devices memory */ | 2187 | /* free sub devices memory */ |
2133 | kfree(vpif_obj.sd); | 2188 | kfree(vpif_obj.sd); |
diff --git a/drivers/media/platform/davinci/vpif_capture.h b/drivers/media/platform/davinci/vpif_capture.h index 0ebb31260369..5a29d9a0cae1 100644 --- a/drivers/media/platform/davinci/vpif_capture.h +++ b/drivers/media/platform/davinci/vpif_capture.h | |||
@@ -142,6 +142,8 @@ struct vpif_device { | |||
142 | struct v4l2_device v4l2_dev; | 142 | struct v4l2_device v4l2_dev; |
143 | struct channel_obj *dev[VPIF_CAPTURE_NUM_CHANNELS]; | 143 | struct channel_obj *dev[VPIF_CAPTURE_NUM_CHANNELS]; |
144 | struct v4l2_subdev **sd; | 144 | struct v4l2_subdev **sd; |
145 | struct v4l2_async_notifier notifier; | ||
146 | struct vpif_capture_config *config; | ||
145 | }; | 147 | }; |
146 | 148 | ||
147 | struct vpif_config_params { | 149 | struct vpif_config_params { |
diff --git a/include/media/davinci/vpif_types.h b/include/media/davinci/vpif_types.h index 3882e0675ccf..e08bcde52d05 100644 --- a/include/media/davinci/vpif_types.h +++ b/include/media/davinci/vpif_types.h | |||
@@ -81,5 +81,7 @@ struct vpif_capture_config { | |||
81 | struct vpif_subdev_info *subdev_info; | 81 | struct vpif_subdev_info *subdev_info; |
82 | int subdev_count; | 82 | int subdev_count; |
83 | const char *card_name; | 83 | const char *card_name; |
84 | struct v4l2_async_subdev **asd; /* Flat array, arranged in groups */ | ||
85 | int *asd_sizes; /* 0-terminated array of asd group sizes */ | ||
84 | }; | 86 | }; |
85 | #endif /* _VPIF_TYPES_H */ | 87 | #endif /* _VPIF_TYPES_H */ |