<commit_before>/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "chipset.h"
#include "clock.h"
#include "common.h"
#include "console.h"
#include "gpio.h"
#include "hooks.h"
#include "host_command.h"
#include "i2c.h"
#include "registers.h"
#include "task.h"
#include "timer.h"
#include "util.h"

/* Console output macros */
#define CPUTS(outstr) cputs(CC_I2C, outstr)
#define CPRINTS(format, args...) cprints(CC_I2C, format, ## args)

/* Transmit timeout in microseconds */
#define I2C_TX_TIMEOUT_MASTER	(10 * MSEC)

/*
 * Max data size for a version 3 request/response packet. This is
 * big enough for EC_CMD_GET_VERSION plus header info.
 */
#define I2C_MAX_HOST_PACKET_SIZE 128

#ifdef CONFIG_HOSTCMD_I2C_SLAVE_ADDR
#if (I2C_PORT_EC == STM32_I2C1_PORT)
#define IRQ_SLAVE STM32_IRQ_I2C1
#else
#define IRQ_SLAVE STM32_IRQ_I2C2
#endif
#endif

/**
 * Wait for ISR register to contain the specified mask.
 *
 * Returns EC_SUCCESS, EC_ERROR_TIMEOUT if timed out waiting, or
 * EC_ERROR_UNKNOWN if an error bit appeared in the status register.
 */
static int wait_isr(int port, int mask)
{
	uint64_t timeout = get_time().val + I2C_TX_TIMEOUT_MASTER;

	while (get_time().val < timeout) {
		int isr = STM32_I2C_ISR(port);

		/* Check for errors */
		if (isr & (STM32_I2C_ISR_ARLO | STM32_I2C_ISR_BERR |
			STM32_I2C_ISR_NACK))
			return EC_ERROR_UNKNOWN;

		/* Check for desired mask */
		if ((isr & mask) == mask)
			return EC_SUCCESS;

		/* I2C is slow, so let other things run while we wait */
		usleep(100);
	}

	return EC_ERROR_TIMEOUT;
}

static void i2c_set_freq_port(const struct i2c_port_t *p)
{
	int port = p->port;

	/* Disable port */
	STM32_I2C_CR1(port) = 0;
	STM32_I2C_CR2(port) = 0;
	/* Set clock frequency */
	switch (p->kbps) {
	case 1000:
		STM32_I2C_TIMINGR(port) = 0x50110103;
		break;
	case 400:
		STM32_I2C_TIMINGR(port) = 0x50330309;
		break;
	case 100:
		STM32_I2C_TIMINGR(port) = 0xB0420F13;
		break;
	default: /* unknown speed, defaults to 100kBps */
		CPRINTS("I2C bad speed %d kBps", p->kbps);
		STM32_I2C_TIMINGR(port) = 0xB0420F13;
	}
	/* Enable port */
	STM32_I2C_CR1(port) = STM32_I2C_CR1_PE;
}

/**
 * Initialize on the specified I2C port.
 *
 * @param p		the I2c port
 */
static void i2c_init_port(const struct i2c_port_t *p)
{
	int port = p->port;

	/* Enable clocks to I2C modules if necessary */
	if (!(STM32_RCC_APB1ENR & (1 << (21 + port))))
		STM32_RCC_APB1ENR |= 1 << (21 + port);

	if (port == 0) {
#if defined(CONFIG_HOSTCMD_I2C_SLAVE_ADDR) && \
defined(CONFIG_LOW_POWER_IDLE) && \
(I2C_PORT_EC == STM32_I2C1_PORT)<commit_msg>stm32f0/i2c: adjust the 100kHz setting to never go above 100kHz<commit_after>/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "chipset.h"
#include "clock.h"
#include "common.h"
#include "console.h"
#include "gpio.h"
#include "hooks.h"
#include "host_command.h"
#include "i2c.h"
#include "registers.h"
#include "task.h"
#include "timer.h"
#include "util.h"

/* Console output macros */
#define CPUTS(outstr) cputs(CC_I2C, outstr)
#define CPRINTS(format, args...) cprints(CC_I2C, format, ## args)

/* Transmit timeout in microseconds */
#define I2C_TX_TIMEOUT_MASTER	(10 * MSEC)

/*
 * Max data size for a version 3 request/response packet. This is
 * big enough for EC_CMD_GET_VERSION plus header info.
 */
#define I2C_MAX_HOST_PACKET_SIZE 128

#ifdef CONFIG_HOSTCMD_I2C_SLAVE_ADDR
#if (I2C_PORT_EC == STM32_I2C1_PORT)
#define IRQ_SLAVE STM32_IRQ_I2C1
#else
#define IRQ_SLAVE STM32_IRQ_I2C2
#endif
#endif

/**
 * Wait for ISR register to contain the specified mask.
 *
 * Returns EC_SUCCESS, EC_ERROR_TIMEOUT if timed out waiting, or
 * EC_ERROR_UNKNOWN if an error bit appeared in the status register.
 */
static int wait_isr(int port, int mask)
{
	uint64_t timeout = get_time().val + I2C_TX_TIMEOUT_MASTER;

	while (get_time().val < timeout) {
		int isr = STM32_I2C_ISR(port);

		/* Check for errors */
		if (isr & (STM32_I2C_ISR_ARLO | STM32_I2C_ISR_BERR |
			STM32_I2C_ISR_NACK))
			return EC_ERROR_UNKNOWN;

		/* Check for desired mask */
		if ((isr & mask) == mask)
			return EC_SUCCESS;

		/* I2C is slow, so let other things run while we wait */
		usleep(100);
	}

	return EC_ERROR_TIMEOUT;
}

static void i2c_set_freq_port(const struct i2c_port_t *p)
{
	int port = p->port;

	/* Disable port */
	STM32_I2C_CR1(port) = 0;
	STM32_I2C_CR2(port) = 0;
	/* Set clock frequency */
	switch (p->kbps) {
	case 1000:
		STM32_I2C_TIMINGR(port) = 0x50110103;
		break;
	case 400:
		STM32_I2C_TIMINGR(port) = 0x50330309;
		break;
	case 100:
		STM32_I2C_TIMINGR(port) = 0xB0421214;
		break;
	default: /* unknown speed, defaults to 100kBps */
		CPRINTS("I2C bad speed %d kBps", p->kbps);
		STM32_I2C_TIMINGR(port) = 0xB0421214;
	}
	/* Enable port */
	STM32_I2C_CR1(port) = STM32_I2C_CR1_PE;
}

/**
 * Initialize on the specified I2C port.
 *
 * @param p		the I2c port
 */
static void i2c_init_port(const struct i2c_port_t *p)
{
	int port = p->port;

	/* Enable clocks to I2C modules if necessary */
	if (!(STM32_RCC_APB1ENR & (1 << (21 + port))))
		STM32_RCC_APB1ENR |= 1 << (21 + port);

	if (port == 0) {
#if defined(CONFIG_HOSTCMD_I2C_SLAVE_ADDR) && \
defined(CONFIG_LOW_POWER_IDLE) && \
(I2C_PORT_EC == STM32_I2C1_PORT)
{'fraction_non_alphanumeric': 0.11885546588407923, 'fraction_numerical': 0.05722670579603815, 'mean_word_length': 4.198284080076263, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3676800', 'n_tokens_mistral': 2472, 'n_tokens_neox': 2251, 'n_words': 576}