FILE
fbtft-sysfs.c
File preview with syntax highlighting.
linux-6.19.14/drivers/staging/fbtft/fbtft-sysfs.c
1// SPDX-License-Identifier: GPL-2.0 2#include "fbtft.h" 3#include "internal.h" 4 5static int get_next_ulong(char **str_p, unsigned long *val, char *sep, int base) 6{ 7 char *p_val; 8 9 if (!str_p || !(*str_p)) 10 return -EINVAL; 11 12 p_val = strsep(str_p, sep); 13 14 if (!p_val) 15 return -EINVAL; 16 17 return kstrtoul(p_val, base, val); 18} 19 20int fbtft_gamma_parse_str(struct fbtft_par *par, u32 *curves, 21 const char *str, int size) 22{ 23 char *str_p, *curve_p = NULL; 24 char *tmp; 25 unsigned long val = 0; 26 int ret = 0; 27 int curve_counter, value_counter; 28 int _count; 29 30 if (!str || !curves) 31 return -EINVAL; 32 33 tmp = kmemdup(str, size + 1, GFP_KERNEL); 34 if (!tmp) 35 return -ENOMEM; 36 37 /* replace optional separators */ 38 str_p = tmp; 39 while (*str_p) { 40 if (*str_p == ',') 41 *str_p = ' '; 42 if (*str_p == ';') 43 *str_p = '\n'; 44 str_p++; 45 } 46 47 str_p = strim(tmp); 48 49 curve_counter = 0; 50 while (str_p) { 51 if (curve_counter == par->gamma.num_curves) { 52 dev_err(par->info->device, "Gamma: Too many curves\n"); 53 ret = -EINVAL; 54 goto out; 55 } 56 curve_p = strsep(&str_p, "\n"); 57 value_counter = 0; 58 while (curve_p) { 59 if (value_counter == par->gamma.num_values) { 60 dev_err(par->info->device, 61 "Gamma: Too many values\n"); 62 ret = -EINVAL; 63 goto out; 64 } 65 ret = get_next_ulong(&curve_p, &val, " ", 16); 66 if (ret) 67 goto out; 68 69 _count = curve_counter * par->gamma.num_values + 70 value_counter; 71 curves[_count] = val; 72 value_counter++; 73 } 74 if (value_counter != par->gamma.num_values) { 75 dev_err(par->info->device, "Gamma: Too few values\n"); 76 ret = -EINVAL; 77 goto out; 78 } 79 curve_counter++; 80 } 81 if (curve_counter != par->gamma.num_curves) { 82 dev_err(par->info->device, "Gamma: Too few curves\n"); 83 ret = -EINVAL; 84 goto out; 85 } 86 87out: 88 kfree(tmp); 89 return ret; 90} 91 92static ssize_t 93sprintf_gamma(struct fbtft_par *par, u32 *curves, char *buf) 94{ 95 ssize_t len = 0; 96 unsigned int i, j; 97 98 mutex_lock(&par->gamma.lock); 99 for (i = 0; i < par->gamma.num_curves; i++) { 100 for (j = 0; j < par->gamma.num_values; j++) 101 len += scnprintf(&buf[len], PAGE_SIZE, 102 "%04x ", curves[i * par->gamma.num_values + j]); 103 buf[len - 1] = '\n'; 104 } 105 mutex_unlock(&par->gamma.lock); 106 107 return len; 108} 109 110static ssize_t store_gamma_curve(struct device *device, 111 struct device_attribute *attr, 112 const char *buf, size_t count) 113{ 114 struct fb_info *fb_info = dev_get_drvdata(device); 115 struct fbtft_par *par = fb_info->par; 116 u32 tmp_curves[FBTFT_GAMMA_MAX_VALUES_TOTAL]; 117 int ret; 118 119 ret = fbtft_gamma_parse_str(par, tmp_curves, buf, count); 120 if (ret) 121 return ret; 122 123 ret = par->fbtftops.set_gamma(par, tmp_curves); 124 if (ret) 125 return ret; 126 127 mutex_lock(&par->gamma.lock); 128 memcpy(par->gamma.curves, tmp_curves, 129 par->gamma.num_curves * par->gamma.num_values * 130 sizeof(tmp_curves[0])); 131 mutex_unlock(&par->gamma.lock); 132 133 return count; 134} 135 136static ssize_t show_gamma_curve(struct device *device, 137 struct device_attribute *attr, char *buf) 138{ 139 struct fb_info *fb_info = dev_get_drvdata(device); 140 struct fbtft_par *par = fb_info->par; 141 142 return sprintf_gamma(par, par->gamma.curves, buf); 143} 144 145static struct device_attribute gamma_device_attrs[] = { 146 __ATTR(gamma, 0660, show_gamma_curve, store_gamma_curve), 147}; 148 149void fbtft_expand_debug_value(unsigned long *debug) 150{ 151 switch (*debug & 0x7) { 152 case 1: 153 *debug |= DEBUG_LEVEL_1; 154 break; 155 case 2: 156 *debug |= DEBUG_LEVEL_2; 157 break; 158 case 3: 159 *debug |= DEBUG_LEVEL_3; 160 break; 161 case 4: 162 *debug |= DEBUG_LEVEL_4; 163 break; 164 case 5: 165 *debug |= DEBUG_LEVEL_5; 166 break; 167 case 6: 168 *debug |= DEBUG_LEVEL_6; 169 break; 170 case 7: 171 *debug = 0xFFFFFFFF; 172 break; 173 } 174} 175 176static ssize_t store_debug(struct device *device, 177 struct device_attribute *attr, 178 const char *buf, size_t count) 179{ 180 struct fb_info *fb_info = dev_get_drvdata(device); 181 struct fbtft_par *par = fb_info->par; 182 int ret; 183 184 ret = kstrtoul(buf, 10, &par->debug); 185 if (ret) 186 return ret; 187 fbtft_expand_debug_value(&par->debug); 188 189 return count; 190} 191 192static ssize_t show_debug(struct device *device, 193 struct device_attribute *attr, char *buf) 194{ 195 struct fb_info *fb_info = dev_get_drvdata(device); 196 struct fbtft_par *par = fb_info->par; 197 198 return sysfs_emit(buf, "%lu\n", par->debug); 199} 200 201static struct device_attribute debug_device_attr = 202 __ATTR(debug, 0660, show_debug, store_debug); 203 204void fbtft_sysfs_init(struct fbtft_par *par) 205{ 206 device_create_file(par->info->dev, &debug_device_attr); 207 if (par->gamma.curves && par->fbtftops.set_gamma) 208 device_create_file(par->info->dev, &gamma_device_attrs[0]); 209} 210 211void fbtft_sysfs_exit(struct fbtft_par *par) 212{ 213 device_remove_file(par->info->dev, &debug_device_attr); 214 if (par->gamma.curves && par->fbtftops.set_gamma) 215 device_remove_file(par->info->dev, &gamma_device_attrs[0]); 216}
~/
Read-only file preview.