diff options
Diffstat (limited to 'drivers/media/video/pvrusb2/pvrusb2-sysfs.c')
-rw-r--r-- | drivers/media/video/pvrusb2/pvrusb2-sysfs.c | 461 |
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 | ||
86 | 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) | ||
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 | ||
105 | 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) | ||
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 | ||
132 | 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) | ||
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 | ||
149 | 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) | ||
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 | ||
166 | 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) | ||
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 | ||
190 | 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) | ||
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 | ||
214 | 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) | ||
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 | ||
239 | 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) | ||
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 | ||
265 | 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, |
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 | ||
284 | static ssize_t store_val_norm(int id,struct device *class_dev, | 253 | static 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 | ||
297 | static ssize_t store_val_custom(int id,struct device *class_dev, | 267 | static 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) \ | ||
324 | static ssize_t sf_name##_##ctl_id(struct device *class_dev, \ | ||
325 | struct device_attribute *attr, char *buf) \ | ||
326 | { return sf_name(ctl_id,class_dev,buf); } | ||
327 | |||
328 | #define CREATE_STORE_INSTANCE(sf_name,ctl_id) \ | ||
329 | static ssize_t sf_name##_##ctl_id(struct device *class_dev, \ | ||
330 | struct 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) \ | ||
334 | CREATE_SHOW_INSTANCE(show_name,ctl_id) \ | ||
335 | CREATE_SHOW_INSTANCE(show_type,ctl_id) \ | ||
336 | CREATE_SHOW_INSTANCE(show_min,ctl_id) \ | ||
337 | CREATE_SHOW_INSTANCE(show_max,ctl_id) \ | ||
338 | CREATE_SHOW_INSTANCE(show_val_norm,ctl_id) \ | ||
339 | CREATE_SHOW_INSTANCE(show_val_custom,ctl_id) \ | ||
340 | CREATE_SHOW_INSTANCE(show_enum,ctl_id) \ | ||
341 | CREATE_SHOW_INSTANCE(show_bits,ctl_id) \ | ||
342 | CREATE_STORE_INSTANCE(store_val_norm,ctl_id) \ | ||
343 | CREATE_STORE_INSTANCE(store_val_custom,ctl_id) \ | ||
344 | |||
345 | CREATE_BATCH(0) | ||
346 | CREATE_BATCH(1) | ||
347 | CREATE_BATCH(2) | ||
348 | CREATE_BATCH(3) | ||
349 | CREATE_BATCH(4) | ||
350 | CREATE_BATCH(5) | ||
351 | CREATE_BATCH(6) | ||
352 | CREATE_BATCH(7) | ||
353 | CREATE_BATCH(8) | ||
354 | CREATE_BATCH(9) | ||
355 | CREATE_BATCH(10) | ||
356 | CREATE_BATCH(11) | ||
357 | CREATE_BATCH(12) | ||
358 | CREATE_BATCH(13) | ||
359 | CREATE_BATCH(14) | ||
360 | CREATE_BATCH(15) | ||
361 | CREATE_BATCH(16) | ||
362 | CREATE_BATCH(17) | ||
363 | CREATE_BATCH(18) | ||
364 | CREATE_BATCH(19) | ||
365 | CREATE_BATCH(20) | ||
366 | CREATE_BATCH(21) | ||
367 | CREATE_BATCH(22) | ||
368 | CREATE_BATCH(23) | ||
369 | CREATE_BATCH(24) | ||
370 | CREATE_BATCH(25) | ||
371 | CREATE_BATCH(26) | ||
372 | CREATE_BATCH(27) | ||
373 | CREATE_BATCH(28) | ||
374 | CREATE_BATCH(29) | ||
375 | CREATE_BATCH(30) | ||
376 | CREATE_BATCH(31) | ||
377 | CREATE_BATCH(32) | ||
378 | CREATE_BATCH(33) | ||
379 | CREATE_BATCH(34) | ||
380 | CREATE_BATCH(35) | ||
381 | CREATE_BATCH(36) | ||
382 | CREATE_BATCH(37) | ||
383 | CREATE_BATCH(38) | ||
384 | CREATE_BATCH(39) | ||
385 | CREATE_BATCH(40) | ||
386 | CREATE_BATCH(41) | ||
387 | CREATE_BATCH(42) | ||
388 | CREATE_BATCH(43) | ||
389 | CREATE_BATCH(44) | ||
390 | CREATE_BATCH(45) | ||
391 | CREATE_BATCH(46) | ||
392 | CREATE_BATCH(47) | ||
393 | CREATE_BATCH(48) | ||
394 | CREATE_BATCH(49) | ||
395 | CREATE_BATCH(50) | ||
396 | CREATE_BATCH(51) | ||
397 | CREATE_BATCH(52) | ||
398 | CREATE_BATCH(53) | ||
399 | CREATE_BATCH(54) | ||
400 | CREATE_BATCH(55) | ||
401 | CREATE_BATCH(56) | ||
402 | CREATE_BATCH(57) | ||
403 | CREATE_BATCH(58) | ||
404 | CREATE_BATCH(59) | ||
405 | |||
406 | struct 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 | |||
445 | static 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 | |||
509 | 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) |
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: |