aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Isely <isely@pobox.com>2008-05-26 05:00:47 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-07-20 06:07:07 -0400
commitf90fe7a3f7fcba0abd89ce0978628ef1d86ecbf9 (patch)
tree5e5c31ba96c9fd39b6bd279627f21b1f6e8091ae
parentfa98e594220b86eb3632de478352e93ebf1201fa (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.c460
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
85static ssize_t show_name(int id,struct device *class_dev,char *buf) 86static 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
104static ssize_t show_type(int id,struct device *class_dev,char *buf) 100static 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
131static ssize_t show_min(int id,struct device *class_dev,char *buf) 122static 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
148static ssize_t show_max(int id,struct device *class_dev,char *buf) 135static 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
165static ssize_t show_val_norm(int id,struct device *class_dev,char *buf) 148static 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
189static ssize_t show_val_custom(int id,struct device *class_dev,char *buf) 167static 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
213static ssize_t show_enum(int id,struct device *class_dev,char *buf) 186static 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
238static ssize_t show_bits(int id,struct device *class_dev,char *buf) 210static 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
264static int store_val_any(int id,int customfl,struct pvr2_sysfs *sfp, 235static 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
283static ssize_t store_val_norm(int id,struct device *class_dev, 253static 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
296static ssize_t store_val_custom(int id,struct device *class_dev, 267static 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) \
323static ssize_t sf_name##_##ctl_id(struct device *class_dev, \
324struct device_attribute *attr, char *buf) \
325{ return sf_name(ctl_id,class_dev,buf); }
326
327#define CREATE_STORE_INSTANCE(sf_name,ctl_id) \
328static ssize_t sf_name##_##ctl_id(struct device *class_dev, \
329struct 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) \
333CREATE_SHOW_INSTANCE(show_name,ctl_id) \
334CREATE_SHOW_INSTANCE(show_type,ctl_id) \
335CREATE_SHOW_INSTANCE(show_min,ctl_id) \
336CREATE_SHOW_INSTANCE(show_max,ctl_id) \
337CREATE_SHOW_INSTANCE(show_val_norm,ctl_id) \
338CREATE_SHOW_INSTANCE(show_val_custom,ctl_id) \
339CREATE_SHOW_INSTANCE(show_enum,ctl_id) \
340CREATE_SHOW_INSTANCE(show_bits,ctl_id) \
341CREATE_STORE_INSTANCE(store_val_norm,ctl_id) \
342CREATE_STORE_INSTANCE(store_val_custom,ctl_id) \
343
344CREATE_BATCH(0)
345CREATE_BATCH(1)
346CREATE_BATCH(2)
347CREATE_BATCH(3)
348CREATE_BATCH(4)
349CREATE_BATCH(5)
350CREATE_BATCH(6)
351CREATE_BATCH(7)
352CREATE_BATCH(8)
353CREATE_BATCH(9)
354CREATE_BATCH(10)
355CREATE_BATCH(11)
356CREATE_BATCH(12)
357CREATE_BATCH(13)
358CREATE_BATCH(14)
359CREATE_BATCH(15)
360CREATE_BATCH(16)
361CREATE_BATCH(17)
362CREATE_BATCH(18)
363CREATE_BATCH(19)
364CREATE_BATCH(20)
365CREATE_BATCH(21)
366CREATE_BATCH(22)
367CREATE_BATCH(23)
368CREATE_BATCH(24)
369CREATE_BATCH(25)
370CREATE_BATCH(26)
371CREATE_BATCH(27)
372CREATE_BATCH(28)
373CREATE_BATCH(29)
374CREATE_BATCH(30)
375CREATE_BATCH(31)
376CREATE_BATCH(32)
377CREATE_BATCH(33)
378CREATE_BATCH(34)
379CREATE_BATCH(35)
380CREATE_BATCH(36)
381CREATE_BATCH(37)
382CREATE_BATCH(38)
383CREATE_BATCH(39)
384CREATE_BATCH(40)
385CREATE_BATCH(41)
386CREATE_BATCH(42)
387CREATE_BATCH(43)
388CREATE_BATCH(44)
389CREATE_BATCH(45)
390CREATE_BATCH(46)
391CREATE_BATCH(47)
392CREATE_BATCH(48)
393CREATE_BATCH(49)
394CREATE_BATCH(50)
395CREATE_BATCH(51)
396CREATE_BATCH(52)
397CREATE_BATCH(53)
398CREATE_BATCH(54)
399CREATE_BATCH(55)
400CREATE_BATCH(56)
401CREATE_BATCH(57)
402CREATE_BATCH(58)
403CREATE_BATCH(59)
404
405struct 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
444static 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
508static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) 281static 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: