Lines Matching +full:- +full:75 +full:mv
1 // SPDX-License-Identifier: GPL-2.0+
3 * Driver for the OLPC XO-1.75 Embedded Controller.
6 * http://wiki.laptop.org/go/XO_1.75_HOST_to_EC_Protocol
19 #include <linux/olpc-ec.h>
59 * (from http://dev.laptop.org/git/users/rsmith/ec-1.75/tree/ec_cmd.h)
62 #define CMD_READ_VOLTAGE 0x10 /* out: u16, *9.76/32, mV */
258 for (p = olpc_xo175_ec_cmds; p->cmd; p++) { in olpc_xo175_ec_resp_len()
259 if (p->cmd == cmd) in olpc_xo175_ec_resp_len()
260 return p->bytes_returned; in olpc_xo175_ec_resp_len()
263 return -EINVAL; in olpc_xo175_ec_resp_len()
268 dev_dbg(&priv->spi->dev, "got debug string [%*pE]\n", in olpc_xo175_ec_flush_logbuf()
269 priv->logbuf_len, priv->logbuf); in olpc_xo175_ec_flush_logbuf()
270 priv->logbuf_len = 0; in olpc_xo175_ec_flush_logbuf()
280 memcpy(&priv->tx_buf, cmd, cmdlen); in olpc_xo175_ec_send_command()
281 priv->xfer.len = cmdlen; in olpc_xo175_ec_send_command()
283 spi_message_init_with_transfers(&priv->msg, &priv->xfer, 1); in olpc_xo175_ec_send_command()
285 priv->msg.complete = olpc_xo175_ec_complete; in olpc_xo175_ec_send_command()
286 priv->msg.context = priv; in olpc_xo175_ec_send_command()
288 ret = spi_async(priv->spi, &priv->msg); in olpc_xo175_ec_send_command()
290 dev_err(&priv->spi->dev, "spi_async() failed %d\n", ret); in olpc_xo175_ec_send_command()
303 struct device *dev = &priv->spi->dev; in olpc_xo175_ec_complete()
310 ret = priv->msg.status; in olpc_xo175_ec_complete()
314 spin_lock_irqsave(&priv->cmd_state_lock, flags); in olpc_xo175_ec_complete()
315 if (priv->cmd_running) { in olpc_xo175_ec_complete()
316 priv->resp_len = 0; in olpc_xo175_ec_complete()
317 priv->cmd_state = CMD_STATE_ERROR_RECEIVED; in olpc_xo175_ec_complete()
318 complete(&priv->cmd_done); in olpc_xo175_ec_complete()
320 spin_unlock_irqrestore(&priv->cmd_state_lock, flags); in olpc_xo175_ec_complete()
322 if (ret != -EINTR) in olpc_xo175_ec_complete()
328 channel = priv->rx_buf.resp.channel; in olpc_xo175_ec_complete()
329 byte = priv->rx_buf.resp.byte; in olpc_xo175_ec_complete()
333 spin_lock_irqsave(&priv->cmd_state_lock, flags); in olpc_xo175_ec_complete()
335 if (!priv->cmd_running) { in olpc_xo175_ec_complete()
338 spin_unlock_irqrestore(&priv->cmd_state_lock, flags); in olpc_xo175_ec_complete()
342 priv->cmd_state = CMD_STATE_CMD_SENT; in olpc_xo175_ec_complete()
343 if (!priv->expected_resp_len) in olpc_xo175_ec_complete()
344 complete(&priv->cmd_done); in olpc_xo175_ec_complete()
347 spin_unlock_irqrestore(&priv->cmd_state_lock, flags); in olpc_xo175_ec_complete()
351 spin_lock_irqsave(&priv->cmd_state_lock, flags); in olpc_xo175_ec_complete()
353 if (!priv->cmd_running) { in olpc_xo175_ec_complete()
356 memset(&priv->cmd, 0, sizeof(priv->cmd)); in olpc_xo175_ec_complete()
357 priv->cmd.command = CMD_ECHO; in olpc_xo175_ec_complete()
360 priv->cmd_state = CMD_STATE_CMD_IN_TX_FIFO; in olpc_xo175_ec_complete()
363 gpiod_set_value_cansleep(priv->gpio_cmd, 0); in olpc_xo175_ec_complete()
364 olpc_xo175_ec_send_command(priv, &priv->cmd, sizeof(priv->cmd)); in olpc_xo175_ec_complete()
366 spin_unlock_irqrestore(&priv->cmd_state_lock, flags); in olpc_xo175_ec_complete()
370 spin_lock_irqsave(&priv->cmd_state_lock, flags); in olpc_xo175_ec_complete()
372 if (!priv->cmd_running) { in olpc_xo175_ec_complete()
374 } else if (priv->resp_len >= priv->expected_resp_len) { in olpc_xo175_ec_complete()
377 priv->resp_data[priv->resp_len++] = byte; in olpc_xo175_ec_complete()
378 if (priv->resp_len == priv->expected_resp_len) { in olpc_xo175_ec_complete()
379 priv->cmd_state = CMD_STATE_RESP_RECEIVED; in olpc_xo175_ec_complete()
380 complete(&priv->cmd_done); in olpc_xo175_ec_complete()
384 spin_unlock_irqrestore(&priv->cmd_state_lock, flags); in olpc_xo175_ec_complete()
388 spin_lock_irqsave(&priv->cmd_state_lock, flags); in olpc_xo175_ec_complete()
390 if (!priv->cmd_running) { in olpc_xo175_ec_complete()
393 priv->resp_data[0] = byte; in olpc_xo175_ec_complete()
394 priv->resp_len = 1; in olpc_xo175_ec_complete()
395 priv->cmd_state = CMD_STATE_ERROR_RECEIVED; in olpc_xo175_ec_complete()
396 complete(&priv->cmd_done); in olpc_xo175_ec_complete()
398 spin_unlock_irqrestore(&priv->cmd_state_lock, flags); in olpc_xo175_ec_complete()
430 input_report_key(priv->pwrbtn, KEY_POWER, 1); in olpc_xo175_ec_complete()
431 input_sync(priv->pwrbtn); in olpc_xo175_ec_complete()
432 input_report_key(priv->pwrbtn, KEY_POWER, 0); in olpc_xo175_ec_complete()
433 input_sync(priv->pwrbtn); in olpc_xo175_ec_complete()
437 pm_wakeup_event(priv->pwrbtn->dev.parent, in olpc_xo175_ec_complete()
450 priv->logbuf[priv->logbuf_len++] = byte; in olpc_xo175_ec_complete()
451 if (priv->logbuf_len == LOG_BUF_SIZE) in olpc_xo175_ec_complete()
461 /* Most non-command packets get the TxFIFO refilled and an ACK. */ in olpc_xo175_ec_complete()
477 struct device *dev = &priv->spi->dev; in olpc_xo175_ec_cmd()
486 return -EOVERFLOW; in olpc_xo175_ec_cmd()
490 if (WARN_ON(priv->suspended)) in olpc_xo175_ec_cmd()
491 return -EBUSY; in olpc_xo175_ec_cmd()
503 if (resp_len > sizeof(priv->resp_data)) { in olpc_xo175_ec_cmd()
505 return -EOVERFLOW; in olpc_xo175_ec_cmd()
514 spin_lock_irqsave(&priv->cmd_state_lock, flags); in olpc_xo175_ec_cmd()
517 init_completion(&priv->cmd_done); in olpc_xo175_ec_cmd()
518 priv->cmd_running = true; in olpc_xo175_ec_cmd()
519 priv->cmd_state = CMD_STATE_WAITING_FOR_SWITCH; in olpc_xo175_ec_cmd()
520 memset(&priv->cmd, 0, sizeof(priv->cmd)); in olpc_xo175_ec_cmd()
521 priv->cmd.command = cmd; in olpc_xo175_ec_cmd()
522 priv->cmd.nr_args = inlen; in olpc_xo175_ec_cmd()
523 priv->cmd.data_len = 0; in olpc_xo175_ec_cmd()
524 memcpy(priv->cmd.args, inbuf, inlen); in olpc_xo175_ec_cmd()
525 priv->expected_resp_len = nr_bytes; in olpc_xo175_ec_cmd()
526 priv->resp_len = 0; in olpc_xo175_ec_cmd()
529 gpiod_set_value_cansleep(priv->gpio_cmd, 1); in olpc_xo175_ec_cmd()
531 spin_unlock_irqrestore(&priv->cmd_state_lock, flags); in olpc_xo175_ec_cmd()
534 if (!wait_for_completion_timeout(&priv->cmd_done, in olpc_xo175_ec_cmd()
537 priv->cmd_state); in olpc_xo175_ec_cmd()
538 gpiod_set_value_cansleep(priv->gpio_cmd, 0); in olpc_xo175_ec_cmd()
539 spi_target_abort(priv->spi); in olpc_xo175_ec_cmd()
541 return -ETIMEDOUT; in olpc_xo175_ec_cmd()
544 spin_lock_irqsave(&priv->cmd_state_lock, flags); in olpc_xo175_ec_cmd()
547 if (priv->cmd_state == CMD_STATE_ERROR_RECEIVED) { in olpc_xo175_ec_cmd()
548 /* EC-provided error is in the single response byte */ in olpc_xo175_ec_cmd()
550 cmd, priv->resp_data[0]); in olpc_xo175_ec_cmd()
551 ret = -EREMOTEIO; in olpc_xo175_ec_cmd()
552 } else if (priv->resp_len != nr_bytes) { in olpc_xo175_ec_cmd()
554 cmd, priv->resp_len, nr_bytes); in olpc_xo175_ec_cmd()
555 ret = -EREMOTEIO; in olpc_xo175_ec_cmd()
558 * We may have 8 bytes in priv->resp, but we only care about in olpc_xo175_ec_cmd()
561 * resp_len <= priv->resp_len and priv->resp_len == nr_bytes. in olpc_xo175_ec_cmd()
563 memcpy(resp, priv->resp_data, resp_len); in olpc_xo175_ec_cmd()
567 gpiod_set_value_cansleep(priv->gpio_cmd, 0); in olpc_xo175_ec_cmd()
568 priv->cmd_running = false; in olpc_xo175_ec_cmd()
570 spin_unlock_irqrestore(&priv->cmd_state_lock, flags); in olpc_xo175_ec_cmd()
616 priv->suspended = true; in olpc_xo175_ec_suspend()
625 priv->suspended = false; in olpc_xo175_ec_resume_noirq()
668 dev_err(&spi->dev, "OLPC EC already registered.\n"); in olpc_xo175_ec_probe()
669 return -EBUSY; in olpc_xo175_ec_probe()
672 priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL); in olpc_xo175_ec_probe()
674 return -ENOMEM; in olpc_xo175_ec_probe()
676 priv->gpio_cmd = devm_gpiod_get(&spi->dev, "cmd", GPIOD_OUT_LOW); in olpc_xo175_ec_probe()
677 if (IS_ERR(priv->gpio_cmd)) { in olpc_xo175_ec_probe()
678 dev_err(&spi->dev, "failed to get cmd gpio: %ld\n", in olpc_xo175_ec_probe()
679 PTR_ERR(priv->gpio_cmd)); in olpc_xo175_ec_probe()
680 return PTR_ERR(priv->gpio_cmd); in olpc_xo175_ec_probe()
683 priv->spi = spi; in olpc_xo175_ec_probe()
685 spin_lock_init(&priv->cmd_state_lock); in olpc_xo175_ec_probe()
686 priv->cmd_state = CMD_STATE_IDLE; in olpc_xo175_ec_probe()
687 init_completion(&priv->cmd_done); in olpc_xo175_ec_probe()
689 priv->logbuf_len = 0; in olpc_xo175_ec_probe()
692 priv->pwrbtn = devm_input_allocate_device(&spi->dev); in olpc_xo175_ec_probe()
693 if (!priv->pwrbtn) in olpc_xo175_ec_probe()
694 return -ENOMEM; in olpc_xo175_ec_probe()
695 priv->pwrbtn->name = "Power Button"; in olpc_xo175_ec_probe()
696 priv->pwrbtn->dev.parent = &spi->dev; in olpc_xo175_ec_probe()
697 input_set_capability(priv->pwrbtn, EV_KEY, KEY_POWER); in olpc_xo175_ec_probe()
698 ret = input_register_device(priv->pwrbtn); in olpc_xo175_ec_probe()
700 dev_err(&spi->dev, "error registering input device: %d\n", ret); in olpc_xo175_ec_probe()
706 priv->xfer.rx_buf = &priv->rx_buf; in olpc_xo175_ec_probe()
707 priv->xfer.tx_buf = &priv->tx_buf; in olpc_xo175_ec_probe()
712 olpc_ec = platform_device_register_resndata(&spi->dev, "olpc-ec", -1, in olpc_xo175_ec_probe()
721 dev_info(&spi->dev, "OLPC XO-1.75 Embedded Controller driver\n"); in olpc_xo175_ec_probe()
732 { .compatible = "olpc,xo1.75-ec" },
738 { "xo1.75-ec", 0 },
745 .name = "olpc-xo175-ec",
755 MODULE_DESCRIPTION("OLPC XO-1.75 Embedded Controller driver");