Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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 */