diff options
author | Mike Isely <isely@pobox.com> | 2008-05-26 05:00:47 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-07-20 06:07:07 -0400 |
commit | f90fe7a3f7fcba0abd89ce0978628ef1d86ecbf9 (patch) | |
tree | 5e5c31ba96c9fd39b6bd279627f21b1f6e8091ae | |
parent | fa98e594220b86eb3632de478352e93ebf1201fa (diff) |
V4L/DVB (7939): pvrusb2: Remove sysfs interface hackery
Back in the early days of the pvrusb2 driver, the kernel class
mechanism in use for the sysfs interface had no means to pass
per-attribute information to the show / store functions. This forced
me to implement a horrible ugly thunking mechanism (i.e. infer the
missing data through the use of dedicated cookie cutter bounce
functions). However now we're using a better mechanism which also
passes enough additional information to the show / store functions
that we no longer need the hack. So eliminate all the crap. Yay!
Signed-off-by: Mike Isely <isely@pobox.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-sysfs.c | 460 |
1 files changed, 114 insertions, 346 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c index 34a234c722c1..46a8c39ba030 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c +++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c | |||
@@ -70,6 +70,7 @@ struct pvr2_sysfs_ctl_item { | |||
70 | struct device_attribute attr_val; | 70 | struct device_attribute attr_val; |
71 | struct device_attribute attr_custom; | 71 | struct device_attribute attr_custom; |
72 | struct pvr2_ctrl *cptr; | 72 | struct pvr2_ctrl *cptr; |
73 | int ctl_id; | ||
73 | struct pvr2_sysfs *chptr; | 74 | struct pvr2_sysfs *chptr; |
74 | struct pvr2_sysfs_ctl_item *item_next; | 75 | struct pvr2_sysfs_ctl_item *item_next; |
75 | struct attribute *attr_gen[7]; | 76 | struct attribute *attr_gen[7]; |
@@ -82,38 +83,29 @@ struct pvr2_sysfs_class { | |||
82 | struct class class; | 83 | struct class class; |
83 | }; | 84 | }; |
84 | 85 | ||
85 | static ssize_t show_name(int id,struct device *class_dev,char *buf) | 86 | static ssize_t show_name(struct device *class_dev, |
87 | struct device_attribute *attr, | ||
88 | char *buf) | ||
86 | { | 89 | { |
87 | struct pvr2_ctrl *cptr; | 90 | struct pvr2_sysfs_ctl_item *cip; |
88 | struct pvr2_sysfs *sfp; | ||
89 | const char *name; | 91 | const char *name; |
90 | 92 | cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_name); | |
91 | sfp = (struct pvr2_sysfs *)class_dev->driver_data; | 93 | name = pvr2_ctrl_get_desc(cip->cptr); |
92 | if (!sfp) return -EINVAL; | 94 | pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s", |
93 | cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); | 95 | cip->chptr, cip->ctl_id, name); |
94 | if (!cptr) return -EINVAL; | ||
95 | |||
96 | name = pvr2_ctrl_get_desc(cptr); | ||
97 | pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s",sfp,id,name); | ||
98 | |||
99 | if (!name) return -EINVAL; | 96 | if (!name) return -EINVAL; |
100 | 97 | return scnprintf(buf, PAGE_SIZE, "%s\n", name); | |
101 | return scnprintf(buf,PAGE_SIZE,"%s\n",name); | ||
102 | } | 98 | } |
103 | 99 | ||
104 | static ssize_t show_type(int id,struct device *class_dev,char *buf) | 100 | static ssize_t show_type(struct device *class_dev, |
101 | struct device_attribute *attr, | ||
102 | char *buf) | ||
105 | { | 103 | { |
106 | struct pvr2_ctrl *cptr; | 104 | struct pvr2_sysfs_ctl_item *cip; |
107 | struct pvr2_sysfs *sfp; | ||
108 | const char *name; | 105 | const char *name; |
109 | enum pvr2_ctl_type tp; | 106 | enum pvr2_ctl_type tp; |
110 | 107 | cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_type); | |
111 | sfp = (struct pvr2_sysfs *)class_dev->driver_data; | 108 | tp = pvr2_ctrl_get_type(cip->cptr); |
112 | if (!sfp) return -EINVAL; | ||
113 | cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); | ||
114 | if (!cptr) return -EINVAL; | ||
115 | |||
116 | tp = pvr2_ctrl_get_type(cptr); | ||
117 | switch (tp) { | 109 | switch (tp) { |
118 | case pvr2_ctl_int: name = "integer"; break; | 110 | case pvr2_ctl_int: name = "integer"; break; |
119 | case pvr2_ctl_enum: name = "enum"; break; | 111 | case pvr2_ctl_enum: name = "enum"; break; |
@@ -121,403 +113,178 @@ static ssize_t show_type(int id,struct device *class_dev,char *buf) | |||
121 | case pvr2_ctl_bool: name = "boolean"; break; | 113 | case pvr2_ctl_bool: name = "boolean"; break; |
122 | default: name = "?"; break; | 114 | default: name = "?"; break; |
123 | } | 115 | } |
124 | pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s",sfp,id,name); | 116 | pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s", |
125 | 117 | cip->chptr, cip->ctl_id, name); | |
126 | if (!name) return -EINVAL; | 118 | if (!name) return -EINVAL; |
127 | 119 | return scnprintf(buf, PAGE_SIZE, "%s\n", name); | |
128 | return scnprintf(buf,PAGE_SIZE,"%s\n",name); | ||
129 | } | 120 | } |
130 | 121 | ||
131 | static ssize_t show_min(int id,struct device *class_dev,char *buf) | 122 | static ssize_t show_min(struct device *class_dev, |
123 | struct device_attribute *attr, | ||
124 | char *buf) | ||
132 | { | 125 | { |
133 | struct pvr2_ctrl *cptr; | 126 | struct pvr2_sysfs_ctl_item *cip; |
134 | struct pvr2_sysfs *sfp; | ||
135 | long val; | 127 | long val; |
136 | 128 | cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_min); | |
137 | sfp = (struct pvr2_sysfs *)class_dev->driver_data; | 129 | val = pvr2_ctrl_get_min(cip->cptr); |
138 | if (!sfp) return -EINVAL; | 130 | pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %ld", |
139 | cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); | 131 | cip->chptr, cip->ctl_id, val); |
140 | if (!cptr) return -EINVAL; | 132 | return scnprintf(buf, PAGE_SIZE, "%ld\n", val); |
141 | val = pvr2_ctrl_get_min(cptr); | ||
142 | |||
143 | pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %ld",sfp,id,val); | ||
144 | |||
145 | return scnprintf(buf,PAGE_SIZE,"%ld\n",val); | ||
146 | } | 133 | } |
147 | 134 | ||
148 | static ssize_t show_max(int id,struct device *class_dev,char *buf) | 135 | static ssize_t show_max(struct device *class_dev, |
136 | struct device_attribute *attr, | ||
137 | char *buf) | ||
149 | { | 138 | { |
150 | struct pvr2_ctrl *cptr; | 139 | struct pvr2_sysfs_ctl_item *cip; |
151 | struct pvr2_sysfs *sfp; | ||
152 | long val; | 140 | long val; |
153 | 141 | cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_max); | |
154 | sfp = (struct pvr2_sysfs *)class_dev->driver_data; | 142 | val = pvr2_ctrl_get_max(cip->cptr); |
155 | if (!sfp) return -EINVAL; | 143 | pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %ld", |
156 | cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); | 144 | cip->chptr, cip->ctl_id, val); |
157 | if (!cptr) return -EINVAL; | 145 | return scnprintf(buf, PAGE_SIZE, "%ld\n", val); |
158 | val = pvr2_ctrl_get_max(cptr); | ||
159 | |||
160 | pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %ld",sfp,id,val); | ||
161 | |||
162 | return scnprintf(buf,PAGE_SIZE,"%ld\n",val); | ||
163 | } | 146 | } |
164 | 147 | ||
165 | static ssize_t show_val_norm(int id,struct device *class_dev,char *buf) | 148 | static ssize_t show_val_norm(struct device *class_dev, |
149 | struct device_attribute *attr, | ||
150 | char *buf) | ||
166 | { | 151 | { |
167 | struct pvr2_ctrl *cptr; | 152 | struct pvr2_sysfs_ctl_item *cip; |
168 | struct pvr2_sysfs *sfp; | 153 | int val; |
169 | int val,ret; | 154 | int ret; |
170 | unsigned int cnt = 0; | 155 | unsigned int cnt = 0; |
171 | 156 | cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_val); | |
172 | sfp = (struct pvr2_sysfs *)class_dev->driver_data; | 157 | ret = pvr2_ctrl_get_value(cip->cptr, &val); |
173 | if (!sfp) return -EINVAL; | ||
174 | cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); | ||
175 | if (!cptr) return -EINVAL; | ||
176 | |||
177 | ret = pvr2_ctrl_get_value(cptr,&val); | ||
178 | if (ret < 0) return ret; | 158 | if (ret < 0) return ret; |
179 | 159 | ret = pvr2_ctrl_value_to_sym(cip->cptr, ~0, val, | |
180 | ret = pvr2_ctrl_value_to_sym(cptr,~0,val, | 160 | buf, PAGE_SIZE - 1, &cnt); |
181 | buf,PAGE_SIZE-1,&cnt); | ||
182 | |||
183 | pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_norm(cid=%d) is %.*s (%d)", | 161 | pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_norm(cid=%d) is %.*s (%d)", |
184 | sfp,id,cnt,buf,val); | 162 | cip->chptr, cip->ctl_id, cnt, buf, val); |
185 | buf[cnt] = '\n'; | 163 | buf[cnt] = '\n'; |
186 | return cnt+1; | 164 | return cnt+1; |
187 | } | 165 | } |
188 | 166 | ||
189 | static ssize_t show_val_custom(int id,struct device *class_dev,char *buf) | 167 | static ssize_t show_val_custom(struct device *class_dev, |
168 | struct device_attribute *attr, | ||
169 | char *buf) | ||
190 | { | 170 | { |
191 | struct pvr2_ctrl *cptr; | 171 | struct pvr2_sysfs_ctl_item *cip; |
192 | struct pvr2_sysfs *sfp; | 172 | int val; |
193 | int val,ret; | 173 | int ret; |
194 | unsigned int cnt = 0; | 174 | unsigned int cnt = 0; |
195 | 175 | cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_custom); | |
196 | sfp = (struct pvr2_sysfs *)class_dev->driver_data; | 176 | ret = pvr2_ctrl_get_value(cip->cptr, &val); |
197 | if (!sfp) return -EINVAL; | ||
198 | cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); | ||
199 | if (!cptr) return -EINVAL; | ||
200 | |||
201 | ret = pvr2_ctrl_get_value(cptr,&val); | ||
202 | if (ret < 0) return ret; | 177 | if (ret < 0) return ret; |
203 | 178 | ret = pvr2_ctrl_custom_value_to_sym(cip->cptr, ~0, val, | |
204 | ret = pvr2_ctrl_custom_value_to_sym(cptr,~0,val, | 179 | buf, PAGE_SIZE - 1, &cnt); |
205 | buf,PAGE_SIZE-1,&cnt); | ||
206 | |||
207 | pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_custom(cid=%d) is %.*s (%d)", | 180 | pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_custom(cid=%d) is %.*s (%d)", |
208 | sfp,id,cnt,buf,val); | 181 | cip->chptr, cip->ctl_id, cnt, buf, val); |
209 | buf[cnt] = '\n'; | 182 | buf[cnt] = '\n'; |
210 | return cnt+1; | 183 | return cnt+1; |
211 | } | 184 | } |
212 | 185 | ||
213 | static ssize_t show_enum(int id,struct device *class_dev,char *buf) | 186 | static ssize_t show_enum(struct device *class_dev, |
187 | struct device_attribute *attr, | ||
188 | char *buf) | ||
214 | { | 189 | { |
215 | struct pvr2_ctrl *cptr; | 190 | struct pvr2_sysfs_ctl_item *cip; |
216 | struct pvr2_sysfs *sfp; | ||
217 | long val; | 191 | long val; |
218 | unsigned int bcnt,ccnt,ecnt; | 192 | unsigned int bcnt, ccnt, ecnt; |
219 | 193 | cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_enum); | |
220 | sfp = (struct pvr2_sysfs *)class_dev->driver_data; | 194 | ecnt = pvr2_ctrl_get_cnt(cip->cptr); |
221 | if (!sfp) return -EINVAL; | ||
222 | cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); | ||
223 | if (!cptr) return -EINVAL; | ||
224 | ecnt = pvr2_ctrl_get_cnt(cptr); | ||
225 | bcnt = 0; | 195 | bcnt = 0; |
226 | for (val = 0; val < ecnt; val++) { | 196 | for (val = 0; val < ecnt; val++) { |
227 | pvr2_ctrl_get_valname(cptr,val,buf+bcnt,PAGE_SIZE-bcnt,&ccnt); | 197 | pvr2_ctrl_get_valname(cip->cptr, val, buf + bcnt, |
198 | PAGE_SIZE - bcnt, &ccnt); | ||
228 | if (!ccnt) continue; | 199 | if (!ccnt) continue; |
229 | bcnt += ccnt; | 200 | bcnt += ccnt; |
230 | if (bcnt >= PAGE_SIZE) break; | 201 | if (bcnt >= PAGE_SIZE) break; |
231 | buf[bcnt] = '\n'; | 202 | buf[bcnt] = '\n'; |
232 | bcnt++; | 203 | bcnt++; |
233 | } | 204 | } |
234 | pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)",sfp,id); | 205 | pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)", |
206 | cip->chptr, cip->ctl_id); | ||
235 | return bcnt; | 207 | return bcnt; |
236 | } | 208 | } |
237 | 209 | ||
238 | static ssize_t show_bits(int id,struct device *class_dev,char *buf) | 210 | static ssize_t show_bits(struct device *class_dev, |
211 | struct device_attribute *attr, | ||
212 | char *buf) | ||
239 | { | 213 | { |
240 | struct pvr2_ctrl *cptr; | 214 | struct pvr2_sysfs_ctl_item *cip; |
241 | struct pvr2_sysfs *sfp; | 215 | int valid_bits, msk; |
242 | int valid_bits,msk; | 216 | unsigned int bcnt, ccnt; |
243 | unsigned int bcnt,ccnt; | 217 | cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_bits); |
244 | 218 | valid_bits = pvr2_ctrl_get_mask(cip->cptr); | |
245 | sfp = (struct pvr2_sysfs *)class_dev->driver_data; | ||
246 | if (!sfp) return -EINVAL; | ||
247 | cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); | ||
248 | if (!cptr) return -EINVAL; | ||
249 | valid_bits = pvr2_ctrl_get_mask(cptr); | ||
250 | bcnt = 0; | 219 | bcnt = 0; |
251 | for (msk = 1; valid_bits; msk <<= 1) { | 220 | for (msk = 1; valid_bits; msk <<= 1) { |
252 | if (!(msk & valid_bits)) continue; | 221 | if (!(msk & valid_bits)) continue; |
253 | valid_bits &= ~msk; | 222 | valid_bits &= ~msk; |
254 | pvr2_ctrl_get_valname(cptr,msk,buf+bcnt,PAGE_SIZE-bcnt,&ccnt); | 223 | pvr2_ctrl_get_valname(cip->cptr, msk, buf + bcnt, |
224 | PAGE_SIZE - bcnt, &ccnt); | ||
255 | bcnt += ccnt; | 225 | bcnt += ccnt; |
256 | if (bcnt >= PAGE_SIZE) break; | 226 | if (bcnt >= PAGE_SIZE) break; |
257 | buf[bcnt] = '\n'; | 227 | buf[bcnt] = '\n'; |
258 | bcnt++; | 228 | bcnt++; |
259 | } | 229 | } |
260 | pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)",sfp,id); | 230 | pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)", |
231 | cip->chptr, cip->ctl_id); | ||
261 | return bcnt; | 232 | return bcnt; |
262 | } | 233 | } |
263 | 234 | ||
264 | static int store_val_any(int id,int customfl,struct pvr2_sysfs *sfp, | 235 | static int store_val_any(struct pvr2_sysfs_ctl_item *cip, int customfl, |
265 | const char *buf,unsigned int count) | 236 | const char *buf,unsigned int count) |
266 | { | 237 | { |
267 | struct pvr2_ctrl *cptr; | ||
268 | int ret; | 238 | int ret; |
269 | int mask,val; | 239 | int mask,val; |
270 | |||
271 | cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); | ||
272 | if (customfl) { | 240 | if (customfl) { |
273 | ret = pvr2_ctrl_custom_sym_to_value(cptr,buf,count,&mask,&val); | 241 | ret = pvr2_ctrl_custom_sym_to_value(cip->cptr, buf, count, |
242 | &mask, &val); | ||
274 | } else { | 243 | } else { |
275 | ret = pvr2_ctrl_sym_to_value(cptr,buf,count,&mask,&val); | 244 | ret = pvr2_ctrl_sym_to_value(cip->cptr, buf, count, |
245 | &mask, &val); | ||
276 | } | 246 | } |
277 | if (ret < 0) return ret; | 247 | if (ret < 0) return ret; |
278 | ret = pvr2_ctrl_set_mask_value(cptr,mask,val); | 248 | ret = pvr2_ctrl_set_mask_value(cip->cptr, mask, val); |
279 | pvr2_hdw_commit_ctl(sfp->channel.hdw); | 249 | pvr2_hdw_commit_ctl(cip->chptr->channel.hdw); |
280 | return ret; | 250 | return ret; |
281 | } | 251 | } |
282 | 252 | ||
283 | static ssize_t store_val_norm(int id,struct device *class_dev, | 253 | static ssize_t store_val_norm(struct device *class_dev, |
284 | const char *buf,size_t count) | 254 | struct device_attribute *attr, |
255 | const char *buf, size_t count) | ||
285 | { | 256 | { |
286 | struct pvr2_sysfs *sfp; | 257 | struct pvr2_sysfs_ctl_item *cip; |
287 | int ret; | 258 | int ret; |
288 | sfp = (struct pvr2_sysfs *)class_dev->driver_data; | 259 | cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_val); |
289 | pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_norm(cid=%d) \"%.*s\"", | 260 | pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_norm(cid=%d) \"%.*s\"", |
290 | sfp,id,(int)count,buf); | 261 | cip->chptr, cip->ctl_id, (int)count, buf); |
291 | ret = store_val_any(id,0,sfp,buf,count); | 262 | ret = store_val_any(cip, 0, buf, count); |
292 | if (!ret) ret = count; | 263 | if (!ret) ret = count; |
293 | return ret; | 264 | return ret; |
294 | } | 265 | } |
295 | 266 | ||
296 | static ssize_t store_val_custom(int id,struct device *class_dev, | 267 | static ssize_t store_val_custom(struct device *class_dev, |
297 | const char *buf,size_t count) | 268 | struct device_attribute *attr, |
269 | const char *buf, size_t count) | ||
298 | { | 270 | { |
299 | struct pvr2_sysfs *sfp; | 271 | struct pvr2_sysfs_ctl_item *cip; |
300 | int ret; | 272 | int ret; |
301 | sfp = (struct pvr2_sysfs *)class_dev->driver_data; | 273 | cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_custom); |
302 | pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_custom(cid=%d) \"%.*s\"", | 274 | pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_custom(cid=%d) \"%.*s\"", |
303 | sfp,id,(int)count,buf); | 275 | cip->chptr, cip->ctl_id, (int)count, buf); |
304 | ret = store_val_any(id,1,sfp,buf,count); | 276 | ret = store_val_any(cip, 1, buf, count); |
305 | if (!ret) ret = count; | 277 | if (!ret) ret = count; |
306 | return ret; | 278 | return ret; |
307 | } | 279 | } |
308 | 280 | ||
309 | /* | ||
310 | Mike Isely <isely@pobox.com> 30-April-2005 | ||
311 | |||
312 | This next batch of horrible preprocessor hackery is needed because the | ||
313 | kernel's device_attribute mechanism fails to pass the actual | ||
314 | attribute through to the show / store functions, which means we have no | ||
315 | way to package up any attribute-specific parameters, like for example the | ||
316 | control id. So we work around this brain-damage by encoding the control | ||
317 | id into the show / store functions themselves and pick the function based | ||
318 | on the control id we're setting up. These macros try to ease the pain. | ||
319 | Yuck. | ||
320 | */ | ||
321 | |||
322 | #define CREATE_SHOW_INSTANCE(sf_name,ctl_id) \ | ||
323 | static ssize_t sf_name##_##ctl_id(struct device *class_dev, \ | ||
324 | struct device_attribute *attr, char *buf) \ | ||
325 | { return sf_name(ctl_id,class_dev,buf); } | ||
326 | |||
327 | #define CREATE_STORE_INSTANCE(sf_name,ctl_id) \ | ||
328 | static ssize_t sf_name##_##ctl_id(struct device *class_dev, \ | ||
329 | struct device_attribute *attr, const char *buf, size_t count) \ | ||
330 | { return sf_name(ctl_id,class_dev,buf,count); } | ||
331 | |||
332 | #define CREATE_BATCH(ctl_id) \ | ||
333 | CREATE_SHOW_INSTANCE(show_name,ctl_id) \ | ||
334 | CREATE_SHOW_INSTANCE(show_type,ctl_id) \ | ||
335 | CREATE_SHOW_INSTANCE(show_min,ctl_id) \ | ||
336 | CREATE_SHOW_INSTANCE(show_max,ctl_id) \ | ||
337 | CREATE_SHOW_INSTANCE(show_val_norm,ctl_id) \ | ||
338 | CREATE_SHOW_INSTANCE(show_val_custom,ctl_id) \ | ||
339 | CREATE_SHOW_INSTANCE(show_enum,ctl_id) \ | ||
340 | CREATE_SHOW_INSTANCE(show_bits,ctl_id) \ | ||
341 | CREATE_STORE_INSTANCE(store_val_norm,ctl_id) \ | ||
342 | CREATE_STORE_INSTANCE(store_val_custom,ctl_id) \ | ||
343 | |||
344 | CREATE_BATCH(0) | ||
345 | CREATE_BATCH(1) | ||
346 | CREATE_BATCH(2) | ||
347 | CREATE_BATCH(3) | ||
348 | CREATE_BATCH(4) | ||
349 | CREATE_BATCH(5) | ||
350 | CREATE_BATCH(6) | ||
351 | CREATE_BATCH(7) | ||
352 | CREATE_BATCH(8) | ||
353 | CREATE_BATCH(9) | ||
354 | CREATE_BATCH(10) | ||
355 | CREATE_BATCH(11) | ||
356 | CREATE_BATCH(12) | ||
357 | CREATE_BATCH(13) | ||
358 | CREATE_BATCH(14) | ||
359 | CREATE_BATCH(15) | ||
360 | CREATE_BATCH(16) | ||
361 | CREATE_BATCH(17) | ||
362 | CREATE_BATCH(18) | ||
363 | CREATE_BATCH(19) | ||
364 | CREATE_BATCH(20) | ||
365 | CREATE_BATCH(21) | ||
366 | CREATE_BATCH(22) | ||
367 | CREATE_BATCH(23) | ||
368 | CREATE_BATCH(24) | ||
369 | CREATE_BATCH(25) | ||
370 | CREATE_BATCH(26) | ||
371 | CREATE_BATCH(27) | ||
372 | CREATE_BATCH(28) | ||
373 | CREATE_BATCH(29) | ||
374 | CREATE_BATCH(30) | ||
375 | CREATE_BATCH(31) | ||
376 | CREATE_BATCH(32) | ||
377 | CREATE_BATCH(33) | ||
378 | CREATE_BATCH(34) | ||
379 | CREATE_BATCH(35) | ||
380 | CREATE_BATCH(36) | ||
381 | CREATE_BATCH(37) | ||
382 | CREATE_BATCH(38) | ||
383 | CREATE_BATCH(39) | ||
384 | CREATE_BATCH(40) | ||
385 | CREATE_BATCH(41) | ||
386 | CREATE_BATCH(42) | ||
387 | CREATE_BATCH(43) | ||
388 | CREATE_BATCH(44) | ||
389 | CREATE_BATCH(45) | ||
390 | CREATE_BATCH(46) | ||
391 | CREATE_BATCH(47) | ||
392 | CREATE_BATCH(48) | ||
393 | CREATE_BATCH(49) | ||
394 | CREATE_BATCH(50) | ||
395 | CREATE_BATCH(51) | ||
396 | CREATE_BATCH(52) | ||
397 | CREATE_BATCH(53) | ||
398 | CREATE_BATCH(54) | ||
399 | CREATE_BATCH(55) | ||
400 | CREATE_BATCH(56) | ||
401 | CREATE_BATCH(57) | ||
402 | CREATE_BATCH(58) | ||
403 | CREATE_BATCH(59) | ||
404 | |||
405 | struct pvr2_sysfs_func_set { | ||
406 | ssize_t (*show_name)(struct device *, | ||
407 | struct device_attribute *attr, char *); | ||
408 | ssize_t (*show_type)(struct device *, | ||
409 | struct device_attribute *attr, char *); | ||
410 | ssize_t (*show_min)(struct device *, | ||
411 | struct device_attribute *attr, char *); | ||
412 | ssize_t (*show_max)(struct device *, | ||
413 | struct device_attribute *attr, char *); | ||
414 | ssize_t (*show_enum)(struct device *, | ||
415 | struct device_attribute *attr, char *); | ||
416 | ssize_t (*show_bits)(struct device *, | ||
417 | struct device_attribute *attr, char *); | ||
418 | ssize_t (*show_val_norm)(struct device *, | ||
419 | struct device_attribute *attr, char *); | ||
420 | ssize_t (*store_val_norm)(struct device *, | ||
421 | struct device_attribute *attr, | ||
422 | const char *,size_t); | ||
423 | ssize_t (*show_val_custom)(struct device *, | ||
424 | struct device_attribute *attr, char *); | ||
425 | ssize_t (*store_val_custom)(struct device *, | ||
426 | struct device_attribute *attr, | ||
427 | const char *,size_t); | ||
428 | }; | ||
429 | |||
430 | #define INIT_BATCH(ctl_id) \ | ||
431 | [ctl_id] = { \ | ||
432 | .show_name = show_name_##ctl_id, \ | ||
433 | .show_type = show_type_##ctl_id, \ | ||
434 | .show_min = show_min_##ctl_id, \ | ||
435 | .show_max = show_max_##ctl_id, \ | ||
436 | .show_enum = show_enum_##ctl_id, \ | ||
437 | .show_bits = show_bits_##ctl_id, \ | ||
438 | .show_val_norm = show_val_norm_##ctl_id, \ | ||
439 | .store_val_norm = store_val_norm_##ctl_id, \ | ||
440 | .show_val_custom = show_val_custom_##ctl_id, \ | ||
441 | .store_val_custom = store_val_custom_##ctl_id, \ | ||
442 | } \ | ||
443 | |||
444 | static struct pvr2_sysfs_func_set funcs[] = { | ||
445 | INIT_BATCH(0), | ||
446 | INIT_BATCH(1), | ||
447 | INIT_BATCH(2), | ||
448 | INIT_BATCH(3), | ||
449 | INIT_BATCH(4), | ||
450 | INIT_BATCH(5), | ||
451 | INIT_BATCH(6), | ||
452 | INIT_BATCH(7), | ||
453 | INIT_BATCH(8), | ||
454 | INIT_BATCH(9), | ||
455 | INIT_BATCH(10), | ||
456 | INIT_BATCH(11), | ||
457 | INIT_BATCH(12), | ||
458 | INIT_BATCH(13), | ||
459 | INIT_BATCH(14), | ||
460 | INIT_BATCH(15), | ||
461 | INIT_BATCH(16), | ||
462 | INIT_BATCH(17), | ||
463 | INIT_BATCH(18), | ||
464 | INIT_BATCH(19), | ||
465 | INIT_BATCH(20), | ||
466 | INIT_BATCH(21), | ||
467 | INIT_BATCH(22), | ||
468 | INIT_BATCH(23), | ||
469 | INIT_BATCH(24), | ||
470 | INIT_BATCH(25), | ||
471 | INIT_BATCH(26), | ||
472 | INIT_BATCH(27), | ||
473 | INIT_BATCH(28), | ||
474 | INIT_BATCH(29), | ||
475 | INIT_BATCH(30), | ||
476 | INIT_BATCH(31), | ||
477 | INIT_BATCH(32), | ||
478 | INIT_BATCH(33), | ||
479 | INIT_BATCH(34), | ||
480 | INIT_BATCH(35), | ||
481 | INIT_BATCH(36), | ||
482 | INIT_BATCH(37), | ||
483 | INIT_BATCH(38), | ||
484 | INIT_BATCH(39), | ||
485 | INIT_BATCH(40), | ||
486 | INIT_BATCH(41), | ||
487 | INIT_BATCH(42), | ||
488 | INIT_BATCH(43), | ||
489 | INIT_BATCH(44), | ||
490 | INIT_BATCH(45), | ||
491 | INIT_BATCH(46), | ||
492 | INIT_BATCH(47), | ||
493 | INIT_BATCH(48), | ||
494 | INIT_BATCH(49), | ||
495 | INIT_BATCH(50), | ||
496 | INIT_BATCH(51), | ||
497 | INIT_BATCH(52), | ||
498 | INIT_BATCH(53), | ||
499 | INIT_BATCH(54), | ||
500 | INIT_BATCH(55), | ||
501 | INIT_BATCH(56), | ||
502 | INIT_BATCH(57), | ||
503 | INIT_BATCH(58), | ||
504 | INIT_BATCH(59), | ||
505 | }; | ||
506 | |||
507 | |||
508 | static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) | 281 | static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) |
509 | { | 282 | { |
510 | struct pvr2_sysfs_ctl_item *cip; | 283 | struct pvr2_sysfs_ctl_item *cip; |
511 | struct pvr2_sysfs_func_set *fp; | ||
512 | struct pvr2_ctrl *cptr; | 284 | struct pvr2_ctrl *cptr; |
513 | unsigned int cnt,acnt; | 285 | unsigned int cnt,acnt; |
514 | int ret; | 286 | int ret; |
515 | 287 | ||
516 | if ((ctl_id < 0) || (ctl_id >= ARRAY_SIZE(funcs))) { | ||
517 | return; | ||
518 | } | ||
519 | |||
520 | fp = funcs + ctl_id; | ||
521 | cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,ctl_id); | 288 | cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,ctl_id); |
522 | if (!cptr) return; | 289 | if (!cptr) return; |
523 | 290 | ||
@@ -526,6 +293,7 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) | |||
526 | pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip); | 293 | pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip); |
527 | 294 | ||
528 | cip->cptr = cptr; | 295 | cip->cptr = cptr; |
296 | cip->ctl_id = ctl_id; | ||
529 | 297 | ||
530 | cip->chptr = sfp; | 298 | cip->chptr = sfp; |
531 | cip->item_next = NULL; | 299 | cip->item_next = NULL; |
@@ -538,19 +306,19 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) | |||
538 | 306 | ||
539 | cip->attr_name.attr.name = "name"; | 307 | cip->attr_name.attr.name = "name"; |
540 | cip->attr_name.attr.mode = S_IRUGO; | 308 | cip->attr_name.attr.mode = S_IRUGO; |
541 | cip->attr_name.show = fp->show_name; | 309 | cip->attr_name.show = show_name; |
542 | 310 | ||
543 | cip->attr_type.attr.name = "type"; | 311 | cip->attr_type.attr.name = "type"; |
544 | cip->attr_type.attr.mode = S_IRUGO; | 312 | cip->attr_type.attr.mode = S_IRUGO; |
545 | cip->attr_type.show = fp->show_type; | 313 | cip->attr_type.show = show_type; |
546 | 314 | ||
547 | cip->attr_min.attr.name = "min_val"; | 315 | cip->attr_min.attr.name = "min_val"; |
548 | cip->attr_min.attr.mode = S_IRUGO; | 316 | cip->attr_min.attr.mode = S_IRUGO; |
549 | cip->attr_min.show = fp->show_min; | 317 | cip->attr_min.show = show_min; |
550 | 318 | ||
551 | cip->attr_max.attr.name = "max_val"; | 319 | cip->attr_max.attr.name = "max_val"; |
552 | cip->attr_max.attr.mode = S_IRUGO; | 320 | cip->attr_max.attr.mode = S_IRUGO; |
553 | cip->attr_max.show = fp->show_max; | 321 | cip->attr_max.show = show_max; |
554 | 322 | ||
555 | cip->attr_val.attr.name = "cur_val"; | 323 | cip->attr_val.attr.name = "cur_val"; |
556 | cip->attr_val.attr.mode = S_IRUGO; | 324 | cip->attr_val.attr.mode = S_IRUGO; |
@@ -560,11 +328,11 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) | |||
560 | 328 | ||
561 | cip->attr_enum.attr.name = "enum_val"; | 329 | cip->attr_enum.attr.name = "enum_val"; |
562 | cip->attr_enum.attr.mode = S_IRUGO; | 330 | cip->attr_enum.attr.mode = S_IRUGO; |
563 | cip->attr_enum.show = fp->show_enum; | 331 | cip->attr_enum.show = show_enum; |
564 | 332 | ||
565 | cip->attr_bits.attr.name = "bit_val"; | 333 | cip->attr_bits.attr.name = "bit_val"; |
566 | cip->attr_bits.attr.mode = S_IRUGO; | 334 | cip->attr_bits.attr.mode = S_IRUGO; |
567 | cip->attr_bits.show = fp->show_bits; | 335 | cip->attr_bits.show = show_bits; |
568 | 336 | ||
569 | if (pvr2_ctrl_is_writable(cptr)) { | 337 | if (pvr2_ctrl_is_writable(cptr)) { |
570 | cip->attr_val.attr.mode |= S_IWUSR|S_IWGRP; | 338 | cip->attr_val.attr.mode |= S_IWUSR|S_IWGRP; |
@@ -575,12 +343,12 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) | |||
575 | cip->attr_gen[acnt++] = &cip->attr_name.attr; | 343 | cip->attr_gen[acnt++] = &cip->attr_name.attr; |
576 | cip->attr_gen[acnt++] = &cip->attr_type.attr; | 344 | cip->attr_gen[acnt++] = &cip->attr_type.attr; |
577 | cip->attr_gen[acnt++] = &cip->attr_val.attr; | 345 | cip->attr_gen[acnt++] = &cip->attr_val.attr; |
578 | cip->attr_val.show = fp->show_val_norm; | 346 | cip->attr_val.show = show_val_norm; |
579 | cip->attr_val.store = fp->store_val_norm; | 347 | cip->attr_val.store = store_val_norm; |
580 | if (pvr2_ctrl_has_custom_symbols(cptr)) { | 348 | if (pvr2_ctrl_has_custom_symbols(cptr)) { |
581 | cip->attr_gen[acnt++] = &cip->attr_custom.attr; | 349 | cip->attr_gen[acnt++] = &cip->attr_custom.attr; |
582 | cip->attr_custom.show = fp->show_val_custom; | 350 | cip->attr_custom.show = show_val_custom; |
583 | cip->attr_custom.store = fp->store_val_custom; | 351 | cip->attr_custom.store = store_val_custom; |
584 | } | 352 | } |
585 | switch (pvr2_ctrl_get_type(cptr)) { | 353 | switch (pvr2_ctrl_get_type(cptr)) { |
586 | case pvr2_ctl_enum: | 354 | case pvr2_ctl_enum: |