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