^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2005 Mike Isely <isely@pobox.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "pvrusb2-sysfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "pvrusb2-hdw.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "pvrusb2-debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "pvrusb2-debugifc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define pvr2_sysfs_trace(...) pvr2_trace(PVR2_TRACE_SYSFS,__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) struct pvr2_sysfs {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct pvr2_channel channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct device *class_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct pvr2_sysfs_debugifc *debugifc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct pvr2_sysfs_ctl_item *item_first;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct pvr2_sysfs_ctl_item *item_last;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct device_attribute attr_v4l_minor_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct device_attribute attr_v4l_radio_minor_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct device_attribute attr_unit_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct device_attribute attr_bus_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct device_attribute attr_hdw_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct device_attribute attr_hdw_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) int v4l_minor_number_created_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) int v4l_radio_minor_number_created_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) int unit_number_created_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) int bus_info_created_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) int hdw_name_created_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) int hdw_desc_created_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct pvr2_sysfs_debugifc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct device_attribute attr_debugcmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct device_attribute attr_debuginfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) int debugcmd_created_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) int debuginfo_created_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct pvr2_sysfs_ctl_item {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct device_attribute attr_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct device_attribute attr_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct device_attribute attr_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct device_attribute attr_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct device_attribute attr_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct device_attribute attr_enum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct device_attribute attr_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct device_attribute attr_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct device_attribute attr_custom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct pvr2_ctrl *cptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) int ctl_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct pvr2_sysfs *chptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct pvr2_sysfs_ctl_item *item_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct attribute *attr_gen[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct attribute_group grp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) int created_ok;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) char name[80];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct pvr2_sysfs_class {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct class class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static ssize_t show_name(struct device *class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct pvr2_sysfs_ctl_item *cip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) name = pvr2_ctrl_get_desc(cip->cptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) cip->chptr, cip->ctl_id, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (!name) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) return scnprintf(buf, PAGE_SIZE, "%s\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static ssize_t show_type(struct device *class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct pvr2_sysfs_ctl_item *cip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) enum pvr2_ctl_type tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) tp = pvr2_ctrl_get_type(cip->cptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) switch (tp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) case pvr2_ctl_int: name = "integer"; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) case pvr2_ctl_enum: name = "enum"; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) case pvr2_ctl_bitmask: name = "bitmask"; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) case pvr2_ctl_bool: name = "boolean"; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) default: name = "?"; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) cip->chptr, cip->ctl_id, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return scnprintf(buf, PAGE_SIZE, "%s\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static ssize_t show_min(struct device *class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct pvr2_sysfs_ctl_item *cip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) val = pvr2_ctrl_get_min(cip->cptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %ld",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) cip->chptr, cip->ctl_id, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return scnprintf(buf, PAGE_SIZE, "%ld\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static ssize_t show_max(struct device *class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct pvr2_sysfs_ctl_item *cip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) val = pvr2_ctrl_get_max(cip->cptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %ld",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) cip->chptr, cip->ctl_id, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return scnprintf(buf, PAGE_SIZE, "%ld\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static ssize_t show_def(struct device *class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct pvr2_sysfs_ctl_item *cip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) unsigned int cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_def);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) ret = pvr2_ctrl_get_def(cip->cptr, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (ret < 0) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) ret = pvr2_ctrl_value_to_sym(cip->cptr, ~0, val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) buf, PAGE_SIZE - 1, &cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) pvr2_sysfs_trace("pvr2_sysfs(%p) show_def(cid=%d) is %.*s (%d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) cip->chptr, cip->ctl_id, cnt, buf, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) buf[cnt] = '\n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return cnt + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static ssize_t show_val_norm(struct device *class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct pvr2_sysfs_ctl_item *cip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) unsigned int cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ret = pvr2_ctrl_get_value(cip->cptr, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (ret < 0) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) ret = pvr2_ctrl_value_to_sym(cip->cptr, ~0, val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) buf, PAGE_SIZE - 1, &cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_norm(cid=%d) is %.*s (%d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) cip->chptr, cip->ctl_id, cnt, buf, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) buf[cnt] = '\n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return cnt+1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static ssize_t show_val_custom(struct device *class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct pvr2_sysfs_ctl_item *cip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) unsigned int cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_custom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) ret = pvr2_ctrl_get_value(cip->cptr, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (ret < 0) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) ret = pvr2_ctrl_custom_value_to_sym(cip->cptr, ~0, val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) buf, PAGE_SIZE - 1, &cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_custom(cid=%d) is %.*s (%d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) cip->chptr, cip->ctl_id, cnt, buf, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) buf[cnt] = '\n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return cnt+1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static ssize_t show_enum(struct device *class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct pvr2_sysfs_ctl_item *cip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) unsigned int bcnt, ccnt, ecnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_enum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) ecnt = pvr2_ctrl_get_cnt(cip->cptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) bcnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) for (val = 0; val < ecnt; val++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) pvr2_ctrl_get_valname(cip->cptr, val, buf + bcnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) PAGE_SIZE - bcnt, &ccnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (!ccnt) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) bcnt += ccnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (bcnt >= PAGE_SIZE) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) buf[bcnt] = '\n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) bcnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) cip->chptr, cip->ctl_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return bcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) static ssize_t show_bits(struct device *class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) struct pvr2_sysfs_ctl_item *cip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) int valid_bits, msk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) unsigned int bcnt, ccnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) valid_bits = pvr2_ctrl_get_mask(cip->cptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) bcnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) for (msk = 1; valid_bits; msk <<= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (!(msk & valid_bits)) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) valid_bits &= ~msk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) pvr2_ctrl_get_valname(cip->cptr, msk, buf + bcnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) PAGE_SIZE - bcnt, &ccnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) bcnt += ccnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (bcnt >= PAGE_SIZE) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) buf[bcnt] = '\n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) bcnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) cip->chptr, cip->ctl_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return bcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static int store_val_any(struct pvr2_sysfs_ctl_item *cip, int customfl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) const char *buf,unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) int mask,val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (customfl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) ret = pvr2_ctrl_custom_sym_to_value(cip->cptr, buf, count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) &mask, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) ret = pvr2_ctrl_sym_to_value(cip->cptr, buf, count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) &mask, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (ret < 0) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) ret = pvr2_ctrl_set_mask_value(cip->cptr, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) pvr2_hdw_commit_ctl(cip->chptr->channel.hdw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static ssize_t store_val_norm(struct device *class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct pvr2_sysfs_ctl_item *cip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_norm(cid=%d) \"%.*s\"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) cip->chptr, cip->ctl_id, (int)count, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) ret = store_val_any(cip, 0, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (!ret) ret = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static ssize_t store_val_custom(struct device *class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct pvr2_sysfs_ctl_item *cip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_custom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) pvr2_sysfs_trace("pvr2_sysfs(%p) store_val_custom(cid=%d) \"%.*s\"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) cip->chptr, cip->ctl_id, (int)count, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) ret = store_val_any(cip, 1, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (!ret) ret = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) struct pvr2_sysfs_ctl_item *cip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) struct pvr2_ctrl *cptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) unsigned int cnt,acnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,ctl_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (!cptr) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) cip = kzalloc(sizeof(*cip),GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (!cip) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) cip->cptr = cptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) cip->ctl_id = ctl_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) cip->chptr = sfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) cip->item_next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (sfp->item_last) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) sfp->item_last->item_next = cip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) sfp->item_first = cip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) sfp->item_last = cip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) sysfs_attr_init(&cip->attr_name.attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) cip->attr_name.attr.name = "name";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) cip->attr_name.attr.mode = S_IRUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) cip->attr_name.show = show_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) sysfs_attr_init(&cip->attr_type.attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) cip->attr_type.attr.name = "type";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) cip->attr_type.attr.mode = S_IRUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) cip->attr_type.show = show_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) sysfs_attr_init(&cip->attr_min.attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) cip->attr_min.attr.name = "min_val";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) cip->attr_min.attr.mode = S_IRUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) cip->attr_min.show = show_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) sysfs_attr_init(&cip->attr_max.attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) cip->attr_max.attr.name = "max_val";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) cip->attr_max.attr.mode = S_IRUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) cip->attr_max.show = show_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) sysfs_attr_init(&cip->attr_def.attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) cip->attr_def.attr.name = "def_val";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) cip->attr_def.attr.mode = S_IRUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) cip->attr_def.show = show_def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) sysfs_attr_init(&cip->attr_val.attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) cip->attr_val.attr.name = "cur_val";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) cip->attr_val.attr.mode = S_IRUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) sysfs_attr_init(&cip->attr_custom.attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) cip->attr_custom.attr.name = "custom_val";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) cip->attr_custom.attr.mode = S_IRUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) sysfs_attr_init(&cip->attr_enum.attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) cip->attr_enum.attr.name = "enum_val";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) cip->attr_enum.attr.mode = S_IRUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) cip->attr_enum.show = show_enum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) sysfs_attr_init(&cip->attr_bits.attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) cip->attr_bits.attr.name = "bit_val";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) cip->attr_bits.attr.mode = S_IRUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) cip->attr_bits.show = show_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (pvr2_ctrl_is_writable(cptr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) cip->attr_val.attr.mode |= S_IWUSR|S_IWGRP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) cip->attr_custom.attr.mode |= S_IWUSR|S_IWGRP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) acnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) cip->attr_gen[acnt++] = &cip->attr_name.attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) cip->attr_gen[acnt++] = &cip->attr_type.attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) cip->attr_gen[acnt++] = &cip->attr_val.attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) cip->attr_gen[acnt++] = &cip->attr_def.attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) cip->attr_val.show = show_val_norm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) cip->attr_val.store = store_val_norm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (pvr2_ctrl_has_custom_symbols(cptr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) cip->attr_gen[acnt++] = &cip->attr_custom.attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) cip->attr_custom.show = show_val_custom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) cip->attr_custom.store = store_val_custom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) switch (pvr2_ctrl_get_type(cptr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) case pvr2_ctl_enum:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) // Control is an enumeration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) cip->attr_gen[acnt++] = &cip->attr_enum.attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) case pvr2_ctl_int:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) // Control is an integer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) cip->attr_gen[acnt++] = &cip->attr_min.attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) cip->attr_gen[acnt++] = &cip->attr_max.attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) case pvr2_ctl_bitmask:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) // Control is an bitmask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) cip->attr_gen[acnt++] = &cip->attr_bits.attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) default: break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) cnt = scnprintf(cip->name,sizeof(cip->name)-1,"ctl_%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) pvr2_ctrl_get_name(cptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) cip->name[cnt] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) cip->grp.name = cip->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) cip->grp.attrs = cip->attr_gen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) ret = sysfs_create_group(&sfp->class_dev->kobj,&cip->grp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) pvr2_trace(PVR2_TRACE_ERROR_LEGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) "sysfs_create_group error: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) cip->created_ok = !0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) static ssize_t debuginfo_show(struct device *, struct device_attribute *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) char *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) static ssize_t debugcmd_show(struct device *, struct device_attribute *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) char *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) static ssize_t debugcmd_store(struct device *, struct device_attribute *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) const char *, size_t count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) struct pvr2_sysfs_debugifc *dip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) dip = kzalloc(sizeof(*dip),GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (!dip) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) sysfs_attr_init(&dip->attr_debugcmd.attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) dip->attr_debugcmd.attr.name = "debugcmd";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) dip->attr_debugcmd.attr.mode = S_IRUGO|S_IWUSR|S_IWGRP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) dip->attr_debugcmd.show = debugcmd_show;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) dip->attr_debugcmd.store = debugcmd_store;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) sysfs_attr_init(&dip->attr_debuginfo.attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) dip->attr_debuginfo.attr.name = "debuginfo";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) dip->attr_debuginfo.attr.mode = S_IRUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) dip->attr_debuginfo.show = debuginfo_show;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) sfp->debugifc = dip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) ret = device_create_file(sfp->class_dev,&dip->attr_debugcmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) pvr2_trace(PVR2_TRACE_ERROR_LEGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) "device_create_file error: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) dip->debugcmd_created_ok = !0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) ret = device_create_file(sfp->class_dev,&dip->attr_debuginfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) pvr2_trace(PVR2_TRACE_ERROR_LEGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) "device_create_file error: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) dip->debuginfo_created_ok = !0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs *sfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (!sfp->debugifc) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (sfp->debugifc->debuginfo_created_ok) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) device_remove_file(sfp->class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) &sfp->debugifc->attr_debuginfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (sfp->debugifc->debugcmd_created_ok) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) device_remove_file(sfp->class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) &sfp->debugifc->attr_debugcmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) kfree(sfp->debugifc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) sfp->debugifc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) static void pvr2_sysfs_add_controls(struct pvr2_sysfs *sfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) unsigned int idx,cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) cnt = pvr2_hdw_get_ctrl_count(sfp->channel.hdw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) for (idx = 0; idx < cnt; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) pvr2_sysfs_add_control(sfp,idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs *sfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) struct pvr2_sysfs_ctl_item *cip1,*cip2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) for (cip1 = sfp->item_first; cip1; cip1 = cip2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) cip2 = cip1->item_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (cip1->created_ok) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) sysfs_remove_group(&sfp->class_dev->kobj,&cip1->grp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) kfree(cip1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) static void pvr2_sysfs_class_release(struct class *class)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) struct pvr2_sysfs_class *clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) clp = container_of(class,struct pvr2_sysfs_class,class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) pvr2_sysfs_trace("Destroying pvr2_sysfs_class id=%p",clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) kfree(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) static void pvr2_sysfs_release(struct device *class_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) pvr2_sysfs_trace("Releasing class_dev id=%p",class_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) kfree(class_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) static void class_dev_destroy(struct pvr2_sysfs *sfp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (!sfp->class_dev) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) pvr2_sysfs_tear_down_debugifc(sfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) pvr2_sysfs_tear_down_controls(sfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (sfp->hdw_desc_created_ok) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) device_remove_file(sfp->class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) &sfp->attr_hdw_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (sfp->hdw_name_created_ok) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) device_remove_file(sfp->class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) &sfp->attr_hdw_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (sfp->bus_info_created_ok) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) device_remove_file(sfp->class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) &sfp->attr_bus_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if (sfp->v4l_minor_number_created_ok) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) device_remove_file(sfp->class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) &sfp->attr_v4l_minor_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (sfp->v4l_radio_minor_number_created_ok) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) device_remove_file(sfp->class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) &sfp->attr_v4l_radio_minor_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (sfp->unit_number_created_ok) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) device_remove_file(sfp->class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) &sfp->attr_unit_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) dev_set_drvdata(sfp->class_dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) dev = sfp->class_dev->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) sfp->class_dev->parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) put_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) device_unregister(sfp->class_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) sfp->class_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) static ssize_t v4l_minor_number_show(struct device *class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) struct pvr2_sysfs *sfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) sfp = dev_get_drvdata(class_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (!sfp) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) return scnprintf(buf,PAGE_SIZE,"%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) pvr2_hdw_v4l_get_minor_number(sfp->channel.hdw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) pvr2_v4l_type_video));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) static ssize_t bus_info_show(struct device *class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) struct pvr2_sysfs *sfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) sfp = dev_get_drvdata(class_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) if (!sfp) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) return scnprintf(buf,PAGE_SIZE,"%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) pvr2_hdw_get_bus_info(sfp->channel.hdw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) static ssize_t hdw_name_show(struct device *class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) struct pvr2_sysfs *sfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) sfp = dev_get_drvdata(class_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (!sfp) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) return scnprintf(buf,PAGE_SIZE,"%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) pvr2_hdw_get_type(sfp->channel.hdw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) static ssize_t hdw_desc_show(struct device *class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct pvr2_sysfs *sfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) sfp = dev_get_drvdata(class_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (!sfp) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) return scnprintf(buf,PAGE_SIZE,"%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) pvr2_hdw_get_desc(sfp->channel.hdw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) static ssize_t v4l_radio_minor_number_show(struct device *class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) struct pvr2_sysfs *sfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) sfp = dev_get_drvdata(class_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (!sfp) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) return scnprintf(buf,PAGE_SIZE,"%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) pvr2_hdw_v4l_get_minor_number(sfp->channel.hdw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) pvr2_v4l_type_radio));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) static ssize_t unit_number_show(struct device *class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) struct pvr2_sysfs *sfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) sfp = dev_get_drvdata(class_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (!sfp) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) return scnprintf(buf,PAGE_SIZE,"%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) pvr2_hdw_get_unit_number(sfp->channel.hdw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) static void class_dev_create(struct pvr2_sysfs *sfp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) struct pvr2_sysfs_class *class_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) struct usb_device *usb_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) struct device *class_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) usb_dev = pvr2_hdw_get_dev(sfp->channel.hdw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (!usb_dev) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) class_dev = kzalloc(sizeof(*class_dev),GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if (!class_dev) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) pvr2_sysfs_trace("Creating class_dev id=%p",class_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) class_dev->class = &class_ptr->class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) dev_set_name(class_dev, "%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) pvr2_hdw_get_device_identifier(sfp->channel.hdw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) class_dev->parent = get_device(&usb_dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) sfp->class_dev = class_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) dev_set_drvdata(class_dev, sfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) ret = device_register(class_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) pvr2_trace(PVR2_TRACE_ERROR_LEGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) "device_register failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) put_device(class_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) sysfs_attr_init(&sfp->attr_v4l_minor_number.attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) sfp->attr_v4l_minor_number.attr.name = "v4l_minor_number";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) sfp->attr_v4l_minor_number.attr.mode = S_IRUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) sfp->attr_v4l_minor_number.show = v4l_minor_number_show;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) sfp->attr_v4l_minor_number.store = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) ret = device_create_file(sfp->class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) &sfp->attr_v4l_minor_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) pvr2_trace(PVR2_TRACE_ERROR_LEGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) "device_create_file error: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) sfp->v4l_minor_number_created_ok = !0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) sysfs_attr_init(&sfp->attr_v4l_radio_minor_number.attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) sfp->attr_v4l_radio_minor_number.attr.name = "v4l_radio_minor_number";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) sfp->attr_v4l_radio_minor_number.attr.mode = S_IRUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) sfp->attr_v4l_radio_minor_number.show = v4l_radio_minor_number_show;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) sfp->attr_v4l_radio_minor_number.store = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) ret = device_create_file(sfp->class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) &sfp->attr_v4l_radio_minor_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) pvr2_trace(PVR2_TRACE_ERROR_LEGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) "device_create_file error: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) sfp->v4l_radio_minor_number_created_ok = !0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) sysfs_attr_init(&sfp->attr_unit_number.attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) sfp->attr_unit_number.attr.name = "unit_number";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) sfp->attr_unit_number.attr.mode = S_IRUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) sfp->attr_unit_number.show = unit_number_show;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) sfp->attr_unit_number.store = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) ret = device_create_file(sfp->class_dev,&sfp->attr_unit_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) pvr2_trace(PVR2_TRACE_ERROR_LEGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) "device_create_file error: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) sfp->unit_number_created_ok = !0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) sysfs_attr_init(&sfp->attr_bus_info.attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) sfp->attr_bus_info.attr.name = "bus_info_str";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) sfp->attr_bus_info.attr.mode = S_IRUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) sfp->attr_bus_info.show = bus_info_show;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) sfp->attr_bus_info.store = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) ret = device_create_file(sfp->class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) &sfp->attr_bus_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) pvr2_trace(PVR2_TRACE_ERROR_LEGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) "device_create_file error: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) sfp->bus_info_created_ok = !0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) sysfs_attr_init(&sfp->attr_hdw_name.attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) sfp->attr_hdw_name.attr.name = "device_hardware_type";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) sfp->attr_hdw_name.attr.mode = S_IRUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) sfp->attr_hdw_name.show = hdw_name_show;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) sfp->attr_hdw_name.store = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) ret = device_create_file(sfp->class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) &sfp->attr_hdw_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) pvr2_trace(PVR2_TRACE_ERROR_LEGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) "device_create_file error: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) sfp->hdw_name_created_ok = !0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) sysfs_attr_init(&sfp->attr_hdw_desc.attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) sfp->attr_hdw_desc.attr.name = "device_hardware_description";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) sfp->attr_hdw_desc.attr.mode = S_IRUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) sfp->attr_hdw_desc.show = hdw_desc_show;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) sfp->attr_hdw_desc.store = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) ret = device_create_file(sfp->class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) &sfp->attr_hdw_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) pvr2_trace(PVR2_TRACE_ERROR_LEGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) "device_create_file error: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) sfp->hdw_desc_created_ok = !0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) pvr2_sysfs_add_controls(sfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) pvr2_sysfs_add_debugifc(sfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) static void pvr2_sysfs_internal_check(struct pvr2_channel *chp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) struct pvr2_sysfs *sfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) sfp = container_of(chp,struct pvr2_sysfs,channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) if (!sfp->channel.mc_head->disconnect_flag) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_sysfs id=%p",sfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) class_dev_destroy(sfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) pvr2_channel_done(&sfp->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) kfree(sfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) struct pvr2_sysfs_class *class_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) struct pvr2_sysfs *sfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) sfp = kzalloc(sizeof(*sfp),GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (!sfp) return sfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_sysfs id=%p",sfp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) pvr2_channel_init(&sfp->channel,mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) sfp->channel.check_func = pvr2_sysfs_internal_check;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) class_dev_create(sfp,class_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) return sfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) struct pvr2_sysfs_class *pvr2_sysfs_class_create(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) struct pvr2_sysfs_class *clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) clp = kzalloc(sizeof(*clp),GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (!clp) return clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) pvr2_sysfs_trace("Creating and registering pvr2_sysfs_class id=%p",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) clp->class.name = "pvrusb2";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) clp->class.class_release = pvr2_sysfs_class_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) clp->class.dev_release = pvr2_sysfs_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if (class_register(&clp->class)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) pvr2_sysfs_trace(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) "Registration failed for pvr2_sysfs_class id=%p",clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) kfree(clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) clp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) return clp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) pvr2_sysfs_trace("Unregistering pvr2_sysfs_class id=%p", clp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) if (clp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) class_unregister(&clp->class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) #ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) static ssize_t debuginfo_show(struct device *class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) struct pvr2_sysfs *sfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) sfp = dev_get_drvdata(class_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (!sfp) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) pvr2_hdw_trigger_module_log(sfp->channel.hdw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) return pvr2_debugifc_print_info(sfp->channel.hdw,buf,PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) static ssize_t debugcmd_show(struct device *class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) struct pvr2_sysfs *sfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) sfp = dev_get_drvdata(class_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) if (!sfp) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) return pvr2_debugifc_print_status(sfp->channel.hdw,buf,PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) static ssize_t debugcmd_store(struct device *class_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) struct pvr2_sysfs *sfp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) sfp = dev_get_drvdata(class_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (!sfp) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) ret = pvr2_debugifc_docmd(sfp->channel.hdw,buf,count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (ret < 0) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) #endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */