1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (C) 2021-2022, Intel Corporation. */ 3 4 #include "ice.h" 5 #include "ice_lib.h" 6 7 /** 8 * ice_gnss_do_write - Write data to internal GNSS receiver 9 * @pf: board private structure 10 * @buf: command buffer 11 * @size: command buffer size 12 * 13 * Write UBX command data to the GNSS receiver 14 * 15 * Return: 16 * * number of bytes written - success 17 * * negative - error code 18 */ 19 static int 20 ice_gnss_do_write(struct ice_pf *pf, const unsigned char *buf, unsigned int size) 21 { 22 struct ice_aqc_link_topo_addr link_topo; 23 struct ice_hw *hw = &pf->hw; 24 unsigned int offset = 0; 25 int err = 0; 26 27 memset(&link_topo, 0, sizeof(struct ice_aqc_link_topo_addr)); 28 link_topo.topo_params.index = ICE_E810T_GNSS_I2C_BUS; 29 link_topo.topo_params.node_type_ctx |= 30 FIELD_PREP(ICE_AQC_LINK_TOPO_NODE_CTX_M, 31 ICE_AQC_LINK_TOPO_NODE_CTX_OVERRIDE); 32 33 /* It's not possible to write a single byte to u-blox. 34 * Write all bytes in a loop until there are 6 or less bytes left. If 35 * there are exactly 6 bytes left, the last write would be only a byte. 36 * In this case, do 4+2 bytes writes instead of 5+1. Otherwise, do the 37 * last 2 to 5 bytes write. 38 */ 39 while (size - offset > ICE_GNSS_UBX_WRITE_BYTES + 1) { 40 err = ice_aq_write_i2c(hw, link_topo, ICE_GNSS_UBX_I2C_BUS_ADDR, 41 cpu_to_le16(buf[offset]), 42 ICE_MAX_I2C_WRITE_BYTES, 43 &buf[offset + 1], NULL); 44 if (err) 45 goto err_out; 46 47 offset += ICE_GNSS_UBX_WRITE_BYTES; 48 } 49 50 /* Single byte would be written. Write 4 bytes instead of 5. */ 51 if (size - offset == ICE_GNSS_UBX_WRITE_BYTES + 1) { 52 err = ice_aq_write_i2c(hw, link_topo, ICE_GNSS_UBX_I2C_BUS_ADDR, 53 cpu_to_le16(buf[offset]), 54 ICE_MAX_I2C_WRITE_BYTES - 1, 55 &buf[offset + 1], NULL); 56 if (err) 57 goto err_out; 58 59 offset += ICE_GNSS_UBX_WRITE_BYTES - 1; 60 } 61 62 /* Do the last write, 2 to 5 bytes. */ 63 err = ice_aq_write_i2c(hw, link_topo, ICE_GNSS_UBX_I2C_BUS_ADDR, 64 cpu_to_le16(buf[offset]), size - offset - 1, 65 &buf[offset + 1], NULL); 66 if (err) 67 goto err_out; 68 69 return size; 70 71 err_out: 72 dev_err(ice_pf_to_dev(pf), "GNSS failed to write, offset=%u, size=%u, err=%d\n", 73 offset, size, err); 74 75 return err; 76 } 77 78 /** 79 * ice_gnss_read - Read data from internal GNSS module 80 * @work: GNSS read work structure 81 * 82 * Read the data from internal GNSS receiver, write it to gnss_dev. 83 */ 84 static void ice_gnss_read(struct kthread_work *work) 85 { 86 struct gnss_serial *gnss = container_of(work, struct gnss_serial, 87 read_work.work); 88 unsigned long delay = ICE_GNSS_POLL_DATA_DELAY_TIME; 89 unsigned int i, bytes_read, data_len, count; 90 struct ice_aqc_link_topo_addr link_topo; 91 struct ice_pf *pf; 92 struct ice_hw *hw; 93 __be16 data_len_b; 94 char *buf = NULL; 95 u8 i2c_params; 96 int err = 0; 97 98 pf = gnss->back; 99 if (!pf) { 100 err = -EFAULT; 101 goto exit; 102 } 103 104 if (!test_bit(ICE_FLAG_GNSS, pf->flags)) 105 return; 106 107 hw = &pf->hw; 108 109 memset(&link_topo, 0, sizeof(struct ice_aqc_link_topo_addr)); 110 link_topo.topo_params.index = ICE_E810T_GNSS_I2C_BUS; 111 link_topo.topo_params.node_type_ctx |= 112 FIELD_PREP(ICE_AQC_LINK_TOPO_NODE_CTX_M, 113 ICE_AQC_LINK_TOPO_NODE_CTX_OVERRIDE); 114 115 i2c_params = ICE_GNSS_UBX_DATA_LEN_WIDTH | 116 ICE_AQC_I2C_USE_REPEATED_START; 117 118 err = ice_aq_read_i2c(hw, link_topo, ICE_GNSS_UBX_I2C_BUS_ADDR, 119 cpu_to_le16(ICE_GNSS_UBX_DATA_LEN_H), 120 i2c_params, (u8 *)&data_len_b, NULL); 121 if (err) 122 goto requeue; 123 124 data_len = be16_to_cpu(data_len_b); 125 if (data_len == 0 || data_len == U16_MAX) 126 goto requeue; 127 128 /* The u-blox has data_len bytes for us to read */ 129 130 data_len = min_t(typeof(data_len), data_len, PAGE_SIZE); 131 132 buf = (char *)get_zeroed_page(GFP_KERNEL); 133 if (!buf) { 134 err = -ENOMEM; 135 goto requeue; 136 } 137 138 /* Read received data */ 139 for (i = 0; i < data_len; i += bytes_read) { 140 unsigned int bytes_left = data_len - i; 141 142 bytes_read = min_t(typeof(bytes_left), bytes_left, 143 ICE_MAX_I2C_DATA_SIZE); 144 145 err = ice_aq_read_i2c(hw, link_topo, ICE_GNSS_UBX_I2C_BUS_ADDR, 146 cpu_to_le16(ICE_GNSS_UBX_EMPTY_DATA), 147 bytes_read, &buf[i], NULL); 148 if (err) 149 goto free_buf; 150 } 151 152 count = gnss_insert_raw(pf->gnss_dev, buf, i); 153 if (count != i) 154 dev_warn(ice_pf_to_dev(pf), 155 "gnss_insert_raw ret=%d size=%d\n", 156 count, i); 157 delay = ICE_GNSS_TIMER_DELAY_TIME; 158 free_buf: 159 free_page((unsigned long)buf); 160 requeue: 161 kthread_queue_delayed_work(gnss->kworker, &gnss->read_work, delay); 162 exit: 163 if (err) 164 dev_dbg(ice_pf_to_dev(pf), "GNSS failed to read err=%d\n", err); 165 } 166 167 /** 168 * ice_gnss_struct_init - Initialize GNSS receiver 169 * @pf: Board private structure 170 * 171 * Initialize GNSS structures and workers. 172 * 173 * Return: 174 * * pointer to initialized gnss_serial struct - success 175 * * NULL - error 176 */ 177 static struct gnss_serial *ice_gnss_struct_init(struct ice_pf *pf) 178 { 179 struct device *dev = ice_pf_to_dev(pf); 180 struct kthread_worker *kworker; 181 struct gnss_serial *gnss; 182 183 gnss = kzalloc(sizeof(*gnss), GFP_KERNEL); 184 if (!gnss) 185 return NULL; 186 187 gnss->back = pf; 188 pf->gnss_serial = gnss; 189 190 kthread_init_delayed_work(&gnss->read_work, ice_gnss_read); 191 kworker = kthread_create_worker(0, "ice-gnss-%s", dev_name(dev)); 192 if (IS_ERR(kworker)) { 193 kfree(gnss); 194 return NULL; 195 } 196 197 gnss->kworker = kworker; 198 199 return gnss; 200 } 201 202 /** 203 * ice_gnss_open - Open GNSS device 204 * @gdev: pointer to the gnss device struct 205 * 206 * Open GNSS device and start filling the read buffer for consumer. 207 * 208 * Return: 209 * * 0 - success 210 * * negative - error code 211 */ 212 static int ice_gnss_open(struct gnss_device *gdev) 213 { 214 struct ice_pf *pf = gnss_get_drvdata(gdev); 215 struct gnss_serial *gnss; 216 217 if (!pf) 218 return -EFAULT; 219 220 if (!test_bit(ICE_FLAG_GNSS, pf->flags)) 221 return -EFAULT; 222 223 gnss = pf->gnss_serial; 224 if (!gnss) 225 return -ENODEV; 226 227 kthread_queue_delayed_work(gnss->kworker, &gnss->read_work, 0); 228 229 return 0; 230 } 231 232 /** 233 * ice_gnss_close - Close GNSS device 234 * @gdev: pointer to the gnss device struct 235 * 236 * Close GNSS device, cancel worker, stop filling the read buffer. 237 */ 238 static void ice_gnss_close(struct gnss_device *gdev) 239 { 240 struct ice_pf *pf = gnss_get_drvdata(gdev); 241 struct gnss_serial *gnss; 242 243 if (!pf) 244 return; 245 246 gnss = pf->gnss_serial; 247 if (!gnss) 248 return; 249 250 kthread_cancel_delayed_work_sync(&gnss->read_work); 251 } 252 253 /** 254 * ice_gnss_write - Write to GNSS device 255 * @gdev: pointer to the gnss device struct 256 * @buf: pointer to the user data 257 * @count: size of the buffer to be sent to the GNSS device 258 * 259 * Return: 260 * * number of written bytes - success 261 * * negative - error code 262 */ 263 static int 264 ice_gnss_write(struct gnss_device *gdev, const unsigned char *buf, 265 size_t count) 266 { 267 struct ice_pf *pf = gnss_get_drvdata(gdev); 268 struct gnss_serial *gnss; 269 270 /* We cannot write a single byte using our I2C implementation. */ 271 if (count <= 1 || count > ICE_GNSS_TTY_WRITE_BUF) 272 return -EINVAL; 273 274 if (!pf) 275 return -EFAULT; 276 277 if (!test_bit(ICE_FLAG_GNSS, pf->flags)) 278 return -EFAULT; 279 280 gnss = pf->gnss_serial; 281 if (!gnss) 282 return -ENODEV; 283 284 return ice_gnss_do_write(pf, buf, count); 285 } 286 287 static const struct gnss_operations ice_gnss_ops = { 288 .open = ice_gnss_open, 289 .close = ice_gnss_close, 290 .write_raw = ice_gnss_write, 291 }; 292 293 /** 294 * ice_gnss_register - Register GNSS receiver 295 * @pf: Board private structure 296 * 297 * Allocate and register GNSS receiver in the Linux GNSS subsystem. 298 * 299 * Return: 300 * * 0 - success 301 * * negative - error code 302 */ 303 static int ice_gnss_register(struct ice_pf *pf) 304 { 305 struct gnss_device *gdev; 306 int ret; 307 308 gdev = gnss_allocate_device(ice_pf_to_dev(pf)); 309 if (!gdev) { 310 dev_err(ice_pf_to_dev(pf), 311 "gnss_allocate_device returns NULL\n"); 312 return -ENOMEM; 313 } 314 315 gdev->ops = &ice_gnss_ops; 316 gdev->type = GNSS_TYPE_UBX; 317 gnss_set_drvdata(gdev, pf); 318 ret = gnss_register_device(gdev); 319 if (ret) { 320 dev_err(ice_pf_to_dev(pf), "gnss_register_device err=%d\n", 321 ret); 322 gnss_put_device(gdev); 323 } else { 324 pf->gnss_dev = gdev; 325 } 326 327 return ret; 328 } 329 330 /** 331 * ice_gnss_deregister - Deregister GNSS receiver 332 * @pf: Board private structure 333 * 334 * Deregister GNSS receiver from the Linux GNSS subsystem, 335 * release its resources. 336 */ 337 static void ice_gnss_deregister(struct ice_pf *pf) 338 { 339 if (pf->gnss_dev) { 340 gnss_deregister_device(pf->gnss_dev); 341 gnss_put_device(pf->gnss_dev); 342 pf->gnss_dev = NULL; 343 } 344 } 345 346 /** 347 * ice_gnss_init - Initialize GNSS support 348 * @pf: Board private structure 349 */ 350 void ice_gnss_init(struct ice_pf *pf) 351 { 352 int ret; 353 354 pf->gnss_serial = ice_gnss_struct_init(pf); 355 if (!pf->gnss_serial) 356 return; 357 358 ret = ice_gnss_register(pf); 359 if (!ret) { 360 set_bit(ICE_FLAG_GNSS, pf->flags); 361 dev_info(ice_pf_to_dev(pf), "GNSS init successful\n"); 362 } else { 363 ice_gnss_exit(pf); 364 dev_err(ice_pf_to_dev(pf), "GNSS init failure\n"); 365 } 366 } 367 368 /** 369 * ice_gnss_exit - Disable GNSS TTY support 370 * @pf: Board private structure 371 */ 372 void ice_gnss_exit(struct ice_pf *pf) 373 { 374 ice_gnss_deregister(pf); 375 clear_bit(ICE_FLAG_GNSS, pf->flags); 376 377 if (pf->gnss_serial) { 378 struct gnss_serial *gnss = pf->gnss_serial; 379 380 kthread_cancel_delayed_work_sync(&gnss->read_work); 381 kthread_destroy_worker(gnss->kworker); 382 gnss->kworker = NULL; 383 384 kfree(gnss); 385 pf->gnss_serial = NULL; 386 } 387 } 388 389 /** 390 * ice_gnss_is_gps_present - Check if GPS HW is present 391 * @hw: pointer to HW struct 392 */ 393 bool ice_gnss_is_gps_present(struct ice_hw *hw) 394 { 395 if (!hw->func_caps.ts_func_info.src_tmr_owned) 396 return false; 397 398 #if IS_ENABLED(CONFIG_PTP_1588_CLOCK) 399 if (ice_is_e810t(hw)) { 400 int err; 401 u8 data; 402 403 err = ice_read_pca9575_reg_e810t(hw, ICE_PCA9575_P0_IN, &data); 404 if (err || !!(data & ICE_E810T_P0_GNSS_PRSNT_N)) 405 return false; 406 } else { 407 return false; 408 } 409 #else 410 if (!ice_is_e810t(hw)) 411 return false; 412 #endif /* IS_ENABLED(CONFIG_PTP_1588_CLOCK) */ 413 414 return true; 415 } 416