1 /* 2 * PTP 1588 clock support - sysfs interface. 3 * 4 * Copyright (C) 2010 OMICRON electronics GmbH 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 */ 20 #include <linux/capability.h> 21 #include <linux/slab.h> 22 23 #include "ptp_private.h" 24 25 static ssize_t clock_name_show(struct device *dev, 26 struct device_attribute *attr, char *page) 27 { 28 struct ptp_clock *ptp = dev_get_drvdata(dev); 29 return snprintf(page, PAGE_SIZE-1, "%s\n", ptp->info->name); 30 } 31 static DEVICE_ATTR_RO(clock_name); 32 33 #define PTP_SHOW_INT(name, var) \ 34 static ssize_t var##_show(struct device *dev, \ 35 struct device_attribute *attr, char *page) \ 36 { \ 37 struct ptp_clock *ptp = dev_get_drvdata(dev); \ 38 return snprintf(page, PAGE_SIZE-1, "%d\n", ptp->info->var); \ 39 } \ 40 static DEVICE_ATTR(name, 0444, var##_show, NULL); 41 42 PTP_SHOW_INT(max_adjustment, max_adj); 43 PTP_SHOW_INT(n_alarms, n_alarm); 44 PTP_SHOW_INT(n_external_timestamps, n_ext_ts); 45 PTP_SHOW_INT(n_periodic_outputs, n_per_out); 46 PTP_SHOW_INT(n_programmable_pins, n_pins); 47 PTP_SHOW_INT(pps_available, pps); 48 49 static ssize_t extts_enable_store(struct device *dev, 50 struct device_attribute *attr, 51 const char *buf, size_t count) 52 { 53 struct ptp_clock *ptp = dev_get_drvdata(dev); 54 struct ptp_clock_info *ops = ptp->info; 55 struct ptp_clock_request req = { .type = PTP_CLK_REQ_EXTTS }; 56 int cnt, enable; 57 int err = -EINVAL; 58 59 cnt = sscanf(buf, "%u %d", &req.extts.index, &enable); 60 if (cnt != 2) 61 goto out; 62 if (req.extts.index >= ops->n_ext_ts) 63 goto out; 64 65 err = ops->enable(ops, &req, enable ? 1 : 0); 66 if (err) 67 goto out; 68 69 return count; 70 out: 71 return err; 72 } 73 static DEVICE_ATTR(extts_enable, 0220, NULL, extts_enable_store); 74 75 static ssize_t extts_fifo_show(struct device *dev, 76 struct device_attribute *attr, char *page) 77 { 78 struct ptp_clock *ptp = dev_get_drvdata(dev); 79 struct timestamp_event_queue *queue = &ptp->tsevq; 80 struct ptp_extts_event event; 81 unsigned long flags; 82 size_t qcnt; 83 int cnt = 0; 84 85 memset(&event, 0, sizeof(event)); 86 87 if (mutex_lock_interruptible(&ptp->tsevq_mux)) 88 return -ERESTARTSYS; 89 90 spin_lock_irqsave(&queue->lock, flags); 91 qcnt = queue_cnt(queue); 92 if (qcnt) { 93 event = queue->buf[queue->head]; 94 queue->head = (queue->head + 1) % PTP_MAX_TIMESTAMPS; 95 } 96 spin_unlock_irqrestore(&queue->lock, flags); 97 98 if (!qcnt) 99 goto out; 100 101 cnt = snprintf(page, PAGE_SIZE, "%u %lld %u\n", 102 event.index, event.t.sec, event.t.nsec); 103 out: 104 mutex_unlock(&ptp->tsevq_mux); 105 return cnt; 106 } 107 static DEVICE_ATTR(fifo, 0444, extts_fifo_show, NULL); 108 109 static ssize_t period_store(struct device *dev, 110 struct device_attribute *attr, 111 const char *buf, size_t count) 112 { 113 struct ptp_clock *ptp = dev_get_drvdata(dev); 114 struct ptp_clock_info *ops = ptp->info; 115 struct ptp_clock_request req = { .type = PTP_CLK_REQ_PEROUT }; 116 int cnt, enable, err = -EINVAL; 117 118 cnt = sscanf(buf, "%u %lld %u %lld %u", &req.perout.index, 119 &req.perout.start.sec, &req.perout.start.nsec, 120 &req.perout.period.sec, &req.perout.period.nsec); 121 if (cnt != 5) 122 goto out; 123 if (req.perout.index >= ops->n_per_out) 124 goto out; 125 126 enable = req.perout.period.sec || req.perout.period.nsec; 127 err = ops->enable(ops, &req, enable); 128 if (err) 129 goto out; 130 131 return count; 132 out: 133 return err; 134 } 135 static DEVICE_ATTR(period, 0220, NULL, period_store); 136 137 static ssize_t pps_enable_store(struct device *dev, 138 struct device_attribute *attr, 139 const char *buf, size_t count) 140 { 141 struct ptp_clock *ptp = dev_get_drvdata(dev); 142 struct ptp_clock_info *ops = ptp->info; 143 struct ptp_clock_request req = { .type = PTP_CLK_REQ_PPS }; 144 int cnt, enable; 145 int err = -EINVAL; 146 147 if (!capable(CAP_SYS_TIME)) 148 return -EPERM; 149 150 cnt = sscanf(buf, "%d", &enable); 151 if (cnt != 1) 152 goto out; 153 154 err = ops->enable(ops, &req, enable ? 1 : 0); 155 if (err) 156 goto out; 157 158 return count; 159 out: 160 return err; 161 } 162 static DEVICE_ATTR(pps_enable, 0220, NULL, pps_enable_store); 163 164 static struct attribute *ptp_attrs[] = { 165 &dev_attr_clock_name.attr, 166 167 &dev_attr_max_adjustment.attr, 168 &dev_attr_n_alarms.attr, 169 &dev_attr_n_external_timestamps.attr, 170 &dev_attr_n_periodic_outputs.attr, 171 &dev_attr_n_programmable_pins.attr, 172 &dev_attr_pps_available.attr, 173 174 &dev_attr_extts_enable.attr, 175 &dev_attr_fifo.attr, 176 &dev_attr_period.attr, 177 &dev_attr_pps_enable.attr, 178 NULL 179 }; 180 181 static umode_t ptp_is_attribute_visible(struct kobject *kobj, 182 struct attribute *attr, int n) 183 { 184 struct device *dev = kobj_to_dev(kobj); 185 struct ptp_clock *ptp = dev_get_drvdata(dev); 186 struct ptp_clock_info *info = ptp->info; 187 umode_t mode = attr->mode; 188 189 if (attr == &dev_attr_extts_enable.attr || 190 attr == &dev_attr_fifo.attr) { 191 if (!info->n_ext_ts) 192 mode = 0; 193 } else if (attr == &dev_attr_period.attr) { 194 if (!info->n_per_out) 195 mode = 0; 196 } else if (attr == &dev_attr_pps_enable.attr) { 197 if (!info->pps) 198 mode = 0; 199 } 200 201 return mode; 202 } 203 204 static const struct attribute_group ptp_group = { 205 .is_visible = ptp_is_attribute_visible, 206 .attrs = ptp_attrs, 207 }; 208 209 const struct attribute_group *ptp_groups[] = { 210 &ptp_group, 211 NULL 212 }; 213 214 static int ptp_pin_name2index(struct ptp_clock *ptp, const char *name) 215 { 216 int i; 217 for (i = 0; i < ptp->info->n_pins; i++) { 218 if (!strcmp(ptp->info->pin_config[i].name, name)) 219 return i; 220 } 221 return -1; 222 } 223 224 static ssize_t ptp_pin_show(struct device *dev, struct device_attribute *attr, 225 char *page) 226 { 227 struct ptp_clock *ptp = dev_get_drvdata(dev); 228 unsigned int func, chan; 229 int index; 230 231 index = ptp_pin_name2index(ptp, attr->attr.name); 232 if (index < 0) 233 return -EINVAL; 234 235 if (mutex_lock_interruptible(&ptp->pincfg_mux)) 236 return -ERESTARTSYS; 237 238 func = ptp->info->pin_config[index].func; 239 chan = ptp->info->pin_config[index].chan; 240 241 mutex_unlock(&ptp->pincfg_mux); 242 243 return snprintf(page, PAGE_SIZE, "%u %u\n", func, chan); 244 } 245 246 static ssize_t ptp_pin_store(struct device *dev, struct device_attribute *attr, 247 const char *buf, size_t count) 248 { 249 struct ptp_clock *ptp = dev_get_drvdata(dev); 250 unsigned int func, chan; 251 int cnt, err, index; 252 253 cnt = sscanf(buf, "%u %u", &func, &chan); 254 if (cnt != 2) 255 return -EINVAL; 256 257 index = ptp_pin_name2index(ptp, attr->attr.name); 258 if (index < 0) 259 return -EINVAL; 260 261 if (mutex_lock_interruptible(&ptp->pincfg_mux)) 262 return -ERESTARTSYS; 263 err = ptp_set_pinfunc(ptp, index, func, chan); 264 mutex_unlock(&ptp->pincfg_mux); 265 if (err) 266 return err; 267 268 return count; 269 } 270 271 int ptp_populate_pin_groups(struct ptp_clock *ptp) 272 { 273 struct ptp_clock_info *info = ptp->info; 274 int err = -ENOMEM, i, n_pins = info->n_pins; 275 276 if (!n_pins) 277 return 0; 278 279 ptp->pin_dev_attr = kcalloc(n_pins, sizeof(*ptp->pin_dev_attr), 280 GFP_KERNEL); 281 if (!ptp->pin_dev_attr) 282 goto no_dev_attr; 283 284 ptp->pin_attr = kcalloc(1 + n_pins, sizeof(*ptp->pin_attr), GFP_KERNEL); 285 if (!ptp->pin_attr) 286 goto no_pin_attr; 287 288 for (i = 0; i < n_pins; i++) { 289 struct device_attribute *da = &ptp->pin_dev_attr[i]; 290 sysfs_attr_init(&da->attr); 291 da->attr.name = info->pin_config[i].name; 292 da->attr.mode = 0644; 293 da->show = ptp_pin_show; 294 da->store = ptp_pin_store; 295 ptp->pin_attr[i] = &da->attr; 296 } 297 298 ptp->pin_attr_group.name = "pins"; 299 ptp->pin_attr_group.attrs = ptp->pin_attr; 300 301 ptp->pin_attr_groups[0] = &ptp->pin_attr_group; 302 303 return 0; 304 305 no_pin_attr: 306 kfree(ptp->pin_dev_attr); 307 no_dev_attr: 308 return err; 309 } 310 311 void ptp_cleanup_pin_groups(struct ptp_clock *ptp) 312 { 313 kfree(ptp->pin_attr); 314 kfree(ptp->pin_dev_attr); 315 } 316