/*
 * Copyright 2011 Google Inc.  All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 */

/* Implementation of per-board codec beeping */

#include <stdio.h>

#include "base/algorithm.h"
#include "base/container_of.h"
#include "base/io.h"
#include "base/time.h"
#include "base/xalloc.h"
#include "drivers/bus/pci/pci.h"
#include "drivers/sound/hda_codec.h"

#define HDA_ICII_COMMAND_REG 0x60
#define HDA_ICII_RESPONSE_REG 0x64
#define HDA_ICII_ICS_REG 0x68
#define   HDA_ICII_ICS_BUSY (1 << 0)
#define   HDA_ICII_ICS_VALID  (1 << 1)

/* Common node IDs. */
#define HDA_ROOT_NODE 0x00

/* HDA verbs. */
#define HDA_VERB(nid, verb, param) ((nid) << 20 | (verb) << 8 | (param))

#define HDA_VERB_GET_PARAMS 0xF00
#define HDA_VERB_SET_BEEP 0x70A

/* GET_PARAMS parameter IDs. */
#define GET_PARAMS_NODE_COUNT 0x04
#define GET_PARAMS_AUDIO_GROUP_CAPS 0x08
#define GET_PARAMS_AUDIO_WIDGET_CAPS 0x09

/* Get Sub-node count fields. */
#define AUDIO_NODE_NUM_SUB_NODES(x) (x & 0x000000ff)
#define AUDIO_NODE_FIRST_SUB_NODE(x) ((x >> 16) & 0x000000ff)

/* Get Audio Function Group Capabilities fields. */
#define AUDIO_GROUP_CAPS_BEEP_GEN 0x10000

/* Get Audio Widget Capabilities fields. */
#define AUDIO_WIDGET_TYPE_BEEP 0x7
#define AUDIO_WIDGET_TYPE(x) (((x) >> 20) & 0x0f)

#define BEEP_FREQ_BASE 12000

/*
 * Wait 50usec for the codec to indicate it is ready. No response would
 * imply that the codec is non-operative.
 */
static int wait_for_ready(uint32_t base)
{
	// Use a 50 usec timeout - the Linux kernel uses the same duration.
	int timeout = 50;

	while (timeout--) {
		uint32_t reg32 = read32((uint32_t *)(base + HDA_ICII_ICS_REG));
		asm("" ::: "memory");
		if (!(reg32 & HDA_ICII_ICS_BUSY))
			return 0;
		udelay(1);
	}

	printf("Audio: wait_for_ready timeout\n");
	return -1;
}

/*
 * Wait 50usec for the codec to indicate that it accepted the previous
 * command. No response would imply that the code is non-operative.
 */
static int wait_for_response(uint32_t base, uint32_t *response)
{
	uint32_t reg32;

	// Send the verb to the codec.
	reg32 = read32((uint32_t *)(base + HDA_ICII_ICS_REG));
	reg32 |= HDA_ICII_ICS_BUSY | HDA_ICII_ICS_VALID;
	write32((uint32_t *)(base + HDA_ICII_ICS_REG), reg32);

	// Use a 50 usec timeout - the Linux kernel uses the same duration.

	int timeout = 50;
	while (timeout--) {
		reg32 = read32((uint32_t *)(base + HDA_ICII_ICS_REG));
		asm("" ::: "memory");
		if ((reg32 & (HDA_ICII_ICS_VALID | HDA_ICII_ICS_BUSY)) ==
				HDA_ICII_ICS_VALID) {
			if (response != NULL)
				*response = read32(
					(uint32_t *)(base +
						     HDA_ICII_RESPONSE_REG));
			return 0;
		}
		udelay(1);
	}

	printf("Audio: wait_for_response timeout\n");
	return -1;
}

/*
 * Wait for the codec to be ready, write the verb, then wait for the
 * codec to send a valid response.
 */
static int exec_one_verb(uint32_t base, uint32_t val, uint32_t *response)
{
	if (wait_for_ready(base) == -1)
		return -1;

	write32((uint32_t *)(base + HDA_ICII_COMMAND_REG), val);

	if (wait_for_response(base, response) == -1)
		return -1;

	return 0;
}

/* Write one verb and ignore the response. */
static int write_one_verb(uint32_t base, uint32_t val)
{
	return exec_one_verb(base, val, NULL);
}

/* Supported sound devices. */
typedef struct pci_device_id {
	uint16_t vendor;
	uint16_t device;
} pci_device_id;

#define PCI_VENDOR_ID_INTEL 0x8086
#define PCI_DEVICE_ID_INTEL_COUGARPOINT_HDA 0x1c20
#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_HDA 0x1e20
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_H_HDA 0x8c20
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_HDA 0x9c20
#define PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_HDA 0x9ca0

/* Supported sound devices. */
static struct pci_device_id supported[] = {
	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COUGARPOINT_HDA},
	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_HDA},
	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_H_HDA},
	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_HDA},
	{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_HDA},
	{}
};

/* Find the base address to talk to the HDA codec. */
static uint32_t get_hda_base(void)
{
	pcidev_t hda_dev;

	for (int i = 0; i < ARRAY_SIZE(supported); i++) {
		if (pci_find_device(supported[i].vendor, supported[i].device,
			            &hda_dev)) {
			return pci_read_resource(hda_dev, 0) & ~0xf;
		}
	}

	printf("Audio: Controller not found!\n");
	return 0;
}

/*
 * Gets the count of sub-nodes and node id they start at for the given
 * super-node.
 */
static uint32_t get_subnode_info(uint32_t base,
				 uint32_t nid,
				 uint32_t *num_sub_nodes,
				 uint32_t *start_sub_node_nid)
{
	int rc;
	uint32_t response;

	rc = exec_one_verb(base,
			   HDA_VERB(nid,
				    HDA_VERB_GET_PARAMS,
				    GET_PARAMS_NODE_COUNT),
			   &response);
	if (rc < 0) {
		printf("Audio: Error reading sub-node info %d.\n", nid);
		return rc;
	}

	*num_sub_nodes = AUDIO_NODE_NUM_SUB_NODES(response);
	*start_sub_node_nid = AUDIO_NODE_FIRST_SUB_NODE(response);
	return 0;
}

/* Searches the audio group for a node that supports beeping. */
static uint32_t find_beep_node_in_group(uint32_t base, uint32_t group_nid)
{
	int rc;
	uint32_t node_count = 0;
	uint32_t current_nid = 0;
	uint32_t end_nid;
	uint32_t response;

	rc = get_subnode_info(base, group_nid, &node_count, &current_nid);
	if (rc < 0)
		return 0;

	end_nid = current_nid + node_count;
	while (current_nid < end_nid) {
		rc = exec_one_verb(base,
				   HDA_VERB(current_nid,
					    HDA_VERB_GET_PARAMS,
					    GET_PARAMS_AUDIO_WIDGET_CAPS),
				   &response);
		if (rc < 0) {
			printf("Audio: Error reading widget caps.\n");
			return 0;
		}

		if(AUDIO_WIDGET_TYPE(response) == AUDIO_WIDGET_TYPE_BEEP)
			return current_nid;

		current_nid++;
	}

	return 0; // No beep node found.
}

/* Checks if the given audio group contains a beep generator. */
static int audio_group_has_beep_node(uint32_t base, uint32_t nid)
{
	int rc;
	uint32_t response;

	rc = exec_one_verb(base,
			   HDA_VERB(nid,
				    HDA_VERB_GET_PARAMS,
				    GET_PARAMS_AUDIO_GROUP_CAPS),
			   &response);
	if (rc < 0) {
		printf("Audio: Error reading audio group caps %d.\n", nid);
		return 0;
	}

	return !!(response & AUDIO_GROUP_CAPS_BEEP_GEN);
}

/*
 * Finds the nid of the beep node if it exists, if not return 0. Starts at the
 * root node, for each sub-node checks if the group contains a beep node. If
 * the group contains a beep node, polls each node in the group until it is
 * found.
 */
static uint32_t get_hda_beep_nid(HdaCodec *codec, uint32_t base)
{
	int rc;
	uint32_t node_count = 0;
	uint32_t current_nid = 0;
	uint32_t end_nid;

	if (codec->beep_nid_override != -1) {
		rc = codec->beep_nid_override;
		return rc;
	}

	rc = get_subnode_info(base, HDA_ROOT_NODE, &node_count, &current_nid);
	if (rc < 0)
		return rc;

	end_nid = current_nid + node_count;
	while (current_nid < end_nid) {
		if (audio_group_has_beep_node(base, current_nid))
			return find_beep_node_in_group(base, current_nid);
		current_nid++;
	}

	return 0; // No beep node found.
}

/* Sets the beep generator with the given divisor. Pass 0 to disable beep. */
static int set_beep_divisor(HdaCodec *codec, uint8_t divider)
{
	uint32_t base;
	uint32_t beep_nid;

	base = get_hda_base();
	beep_nid = get_hda_beep_nid(codec, base);
	if (beep_nid <= 0) {
		printf("Audio: Failed to find a beep-capable node.\n");
		return -1;
	}
	return write_one_verb(base,
			      HDA_VERB(beep_nid, HDA_VERB_SET_BEEP, divider));
}

static int hda_codec_start(SoundOps *me, uint32_t frequency)
{
	uint8_t divider_val;
	HdaCodec *codec = container_of(me, HdaCodec, ops);

	if (frequency == 0)
		divider_val = 0;	// off
	else if (frequency > BEEP_FREQ_BASE)
		divider_val = 1;
	else if (frequency < BEEP_FREQ_BASE / 0xFF)
		divider_val = 0xff;
	else
		divider_val = (uint8_t)(0xFF & (BEEP_FREQ_BASE / frequency));

	return set_beep_divisor(codec, divider_val);
}

static int hda_codec_stop(SoundOps *me)
{
	HdaCodec *codec = container_of(me, HdaCodec, ops);
	return set_beep_divisor(codec, 0);
}

static int hda_codec_play(SoundOps *me, uint32_t msec, uint32_t frequency)
{
	int res = sound_start(frequency);
	mdelay(msec);
	res |= sound_stop();
	return res;
}

HdaCodec *new_hda_codec(void)
{
	HdaCodec *codec = xzalloc(sizeof(*codec));
	codec->ops.start = &hda_codec_start;
	codec->ops.stop = &hda_codec_stop;
	codec->ops.play = &hda_codec_play;
	codec->beep_nid_override = -1;
	return codec;
}

void set_hda_beep_nid_override(HdaCodec *codec, int nid)
{
	codec->beep_nid_override = nid;
}
