/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include <assert.h>
#include <string.h>
#include <errno.h>
#include "os/mynewt.h"
#include <bsp.h>
#include <hal/hal_bsp.h>
#include <pwm/pwm.h>
#include <mcu/cmsis_nvic.h>

/* Nordic headers */
#include <nrfx.h>
#include <nrfx_pwm.h>
#include <nrf_pwm.h>

/* Mynewt Nordic driver */
#include "pwm_nrf52/pwm_nrf52.h"

/* Max number on PWM instances on existing nRF52xxx MCUs */
#define NRF52_PWM_MAX_INSTANCES     4

struct nrf52_pwm_dev_global {
    bool in_use;
    bool playing;
    nrfx_pwm_t drv_instance;
    nrfx_pwm_config_t config;
    nrf_pwm_values_individual_t duty_cycles;
    uint32_t n_cycles;
    nrfx_pwm_flag_t flags;
    nrfx_pwm_handler_t internal_handler;
    user_handler_t cycle_handler;
    user_handler_t seq_end_handler;
    void* cycle_data;
    void* seq_end_data;
};

static struct nrf52_pwm_dev_global instances[] =
{
#if MYNEWT_VAL(PWM_0)
    [0].in_use = false,
    [0].playing = false,
    [0].drv_instance = NRFX_PWM_INSTANCE(0),
    [0].config = NRFX_PWM_DEFAULT_CONFIG,
    [0].flags = NRFX_PWM_FLAG_LOOP,
    [0].duty_cycles = {0},
    [0].n_cycles = 1,
    [0].internal_handler = NULL,
    [0].cycle_handler = NULL,
    [0].cycle_data = NULL,
    [0].seq_end_handler = NULL,
    [0].seq_end_data = NULL
#endif
#if MYNEWT_VAL(PWM_1)
    ,
    [1].in_use = false,
    [1].playing = false,
    [1].drv_instance = NRFX_PWM_INSTANCE(1),
    [1].config = NRFX_PWM_DEFAULT_CONFIG,
    [1].flags = NRFX_PWM_FLAG_LOOP,
    [1].duty_cycles = {0},
    [1].n_cycles = 1,
    [1].internal_handler = NULL,
    [1].cycle_handler = NULL,
    [1].cycle_data = NULL,
    [1].seq_end_handler = NULL,
    [1].seq_end_data = NULL
#endif
#if MYNEWT_VAL(PWM_2)
    ,
    [2].in_use = false,
    [2].playing = false,
    [2].drv_instance = NRFX_PWM_INSTANCE(2),
    [2].config = NRFX_PWM_DEFAULT_CONFIG,
    [2].flags = NRFX_PWM_FLAG_LOOP,
    [2].duty_cycles = {0},
    [2].n_cycles = 1,
    [2].internal_handler = NULL,
    [2].cycle_handler = NULL,
    [2].cycle_data = NULL,
    [2].seq_end_handler = NULL,
    [2].seq_end_data = NULL
#endif
#if MYNEWT_VAL(PWM_3)
    ,
    [3].in_use = false,
    [3].playing = false,
    [3].drv_instance = NRFX_PWM_INSTANCE(3),
    [3].config = NRFX_PWM_DEFAULT_CONFIG,
    [3].flags = NRFX_PWM_FLAG_LOOP,
    [3].duty_cycles = {0},
    [3].n_cycles = 1,
    [3].internal_handler = NULL,
    [3].cycle_handler = NULL,
    [3].cycle_data = NULL,
    [3].seq_end_handler = NULL,
    [3].seq_end_data = NULL
#endif
};

#if MYNEWT_VAL(PWM_0)
static void handler_0(nrfx_pwm_evt_type_t event_type)
{
    switch (event_type)
    {
    case NRFX_PWM_EVT_END_SEQ0 :
    case NRFX_PWM_EVT_END_SEQ1 :
        instances[0].cycle_handler(instances[0].cycle_data);
        break;

    case NRFX_PWM_EVT_FINISHED :
        instances[0].seq_end_handler(instances[0].seq_end_data);
        break;

    case NRFX_PWM_EVT_STOPPED :
        break;

    default:
        assert(0);
    }
}
#endif

#if MYNEWT_VAL(PWM_1)
static void handler_1(nrfx_pwm_evt_type_t event_type)
{
    switch (event_type)
    {
    case NRFX_PWM_EVT_END_SEQ0 :
    case NRFX_PWM_EVT_END_SEQ1 :
        instances[1].cycle_handler(instances[1].cycle_data);
        break;

    case NRFX_PWM_EVT_FINISHED :
        instances[1].seq_end_handler(instances[1].seq_end_data);
        break;

    case NRFX_PWM_EVT_STOPPED :
        break;

    default:
        assert(0);
    }
}
#endif

#if MYNEWT_VAL(PWM_2)
static void handler_2(nrfx_pwm_evt_type_t event_type)
{
    switch (event_type)
    {
    case NRFX_PWM_EVT_END_SEQ0 :
    case NRFX_PWM_EVT_END_SEQ1 :
        instances[2].cycle_handler(instances[2].cycle_data);
        break;

    case NRFX_PWM_EVT_FINISHED :
        instances[2].seq_end_handler(instances[2].seq_end_data);
        break;

    case NRFX_PWM_EVT_STOPPED :
        break;

    default:
        assert(0);
    }

}
#endif

#if MYNEWT_VAL(PWM_3)
static void handler_3(nrfx_pwm_evt_type_t event_type)
{
    switch (event_type)
    {
    case NRFX_PWM_EVT_END_SEQ0 :
    case NRFX_PWM_EVT_END_SEQ1 :
        instances[3].cycle_handler(instances[3].cycle_data);
        break;

    case NRFX_PWM_EVT_FINISHED :
        instances[3].seq_end_handler(instances[3].seq_end_data);
        break;

    case NRFX_PWM_EVT_STOPPED :
        break;

    default:
        assert(0);
    }
}
#endif

static nrfx_pwm_handler_t internal_handlers[] = {
#if MYNEWT_VAL(PWM_0)
handler_0
#endif
#if MYNEWT_VAL(PWM_1)
,
handler_1
#endif
#if MYNEWT_VAL(PWM_2)
,
handler_2
#endif
#if MYNEWT_VAL(PWM_3)
,
handler_3
#endif
};

/**
 * Initialize a driver instance.
 */
static int
init_instance(int inst_id, nrfx_pwm_config_t* init_conf)
{
    nrfx_pwm_config_t *config;

    config = &instances[inst_id].config;
    if (!init_conf) {
        config->output_pins[0] = NRFX_PWM_PIN_NOT_USED;
        config->output_pins[1] = NRFX_PWM_PIN_NOT_USED;
        config->output_pins[2] = NRFX_PWM_PIN_NOT_USED;
        config->output_pins[3] = NRFX_PWM_PIN_NOT_USED;
        config->irq_priority = 3; /* APP_IRQ_PRIORITY_LOW */
        config->base_clock   = NRF_PWM_CLK_1MHz;
        config->count_mode   = NRF_PWM_MODE_UP;
        config->top_value    = 10000;
        config->load_mode    = NRF_PWM_LOAD_INDIVIDUAL;
        config->step_mode    = NRF_PWM_STEP_AUTO;
    } else {
        memcpy(config, init_conf, sizeof(nrfx_pwm_config_t));
    }
    return (0);
}

/**
 * Cleanup a driver instance.
 */
static void
cleanup_instance(int inst_id)
{
    instances[inst_id].in_use = false;
    instances[inst_id].playing = false;
    instances[inst_id].internal_handler = NULL;
    instances[inst_id].cycle_handler = NULL;
    instances[inst_id].seq_end_handler = NULL;
    instances[inst_id].cycle_data = NULL;
    instances[inst_id].seq_end_data = NULL;
    memset((uint16_t *) &instances[inst_id].duty_cycles,
           0x00,
           4 * sizeof(uint16_t));
}

/**
 * Open the NRF52 PWM device
 *
 * This function locks the device for access from other tasks.
 *
 * @param odev The OS device to open
 * @param wait The time in MS to wait.  If 0 specified, returns immediately
 *             if resource unavailable.  If OS_WAIT_FOREVER specified, blocks
 *             until resource is available.
 * @param arg  Argument provided by higher layer to open, in this case
 *             it can be a nrf_drv_pwm_config_t, to override the default
 *             configuration.
 *
 * @return 0 on success, non-zero error code on failure.
 */
static int
nrf52_pwm_open(struct os_dev *odev, uint32_t wait, void *arg)
{
    struct pwm_dev *dev;
    int stat = 0;
    int inst_id;
    dev = (struct pwm_dev *) odev;
    inst_id = dev->pwm_instance_id;

    if (instances[inst_id].in_use) {
        return (EINVAL);
    }
    instances[inst_id].in_use = true;

    if (os_started()) {
        stat = os_mutex_pend(&dev->pwm_lock, wait);
        if (stat != OS_OK) {
            return (stat);
        }
    }

    if (odev->od_flags & OS_DEV_F_STATUS_OPEN) {
        os_mutex_release(&dev->pwm_lock);
        stat = OS_EBUSY;
        return (stat);
    }

    stat = init_instance(inst_id, arg);
    if (stat) {
        return (stat);
    }

    return (0);
}

/**
 * Close the NRF52 PWM device.
 *
 * This function unlocks the device.
 *
 * @param odev The device to close.
 *
 * @return 0 on success, non-zero error code on failure.
 */
static int
nrf52_pwm_close(struct os_dev *odev)
{
    struct pwm_dev *dev;
    int inst_id;

    dev = (struct pwm_dev *) odev;
    inst_id = dev->pwm_instance_id;

    if (!instances[inst_id].in_use) {
        return (EINVAL);
    }

    if(instances[inst_id].playing) {
        nrfx_pwm_uninit(&instances[inst_id].drv_instance);
    }

    cleanup_instance(inst_id);

    if (os_started()) {
        os_mutex_release(&dev->pwm_lock);
    }

    return (0);
}

/**
 * Play using current configuration.
 */
static void
play_current_config(struct nrf52_pwm_dev_global *instance)
{
    nrf_pwm_sequence_t const seq =
        {
            .values.p_individual = &instance->duty_cycles,
            .length              = 4,
            .repeats             = 0,
            .end_delay           = 0
        };

    nrfx_pwm_simple_playback(&instance->drv_instance,
                             &seq,
                             instance->n_cycles,
                             instance->flags);
}

/**
 * Configure a PWM device.
 *
 * @param dev The device to configure.
 * @param cfg Configuration data for this device. If NULL the device will be
 * given default configuration values.
 *
 * @return 0 on success, non-zero error code on failure.
 */
int
nrf52_pwm_configure_device(struct pwm_dev *dev, struct pwm_dev_cfg *cfg)
{
    int inst_id = dev->pwm_instance_id;
    struct nrf52_pwm_dev_global *instance = &instances[inst_id];

    instance->n_cycles = (cfg->n_cycles) ? cfg->n_cycles : 1;

    /* Configure Interrupts  */
    if (cfg->cycle_handler || cfg->seq_end_handler) {
        instance->config.irq_priority = cfg->int_prio;
        instance->internal_handler = internal_handlers[inst_id];
        instance->cycle_handler = (user_handler_t) cfg->cycle_handler;
        instance->seq_end_handler = (user_handler_t) cfg->seq_end_handler;
        instance->cycle_data = cfg->cycle_data;
        instance->seq_end_data = cfg->seq_end_data;
    } else {
        instance->internal_handler = NULL;
    }

    instance->flags = (instance->n_cycles > 1) ?
        0 :
        NRFX_PWM_FLAG_LOOP;
    instance->flags |= (instance->cycle_handler) ?
        (NRFX_PWM_FLAG_SIGNAL_END_SEQ0 | NRFX_PWM_FLAG_SIGNAL_END_SEQ0) :
        0;
    instance->flags |= (instance->seq_end_handler) ?
        0 :
        NRFX_PWM_FLAG_NO_EVT_FINISHED;

    if (instance->playing) {
        nrfx_pwm_uninit(&instance->drv_instance);
        nrfx_pwm_init(&instance->drv_instance,
                      &instance->config,
                      instance->internal_handler);

        play_current_config(instance);
    }
    return (0);
}

/**
 * Configure a channel on the PWM device.
 *
 * @param dev The device to configure.
 * @param cnum The channel number to configure.
 * @param cfg  A pwm_chan_cfg data structure, where .
 *
 * @return 0 on success, non-zero error code on failure.
 */
static int
nrf52_pwm_configure_channel(struct pwm_dev *dev,
                            uint8_t cnum,
                            struct pwm_chan_cfg *cfg)
{
    int inst_id = dev->pwm_instance_id;
    struct nrf52_pwm_dev_global *instance = &instances[inst_id];
    nrfx_pwm_config_t *config = &instance->config;

    if (!instance->in_use) {
        return (EINVAL);
    }

    config->output_pins[cnum] = (uint8_t) cfg->pin;
    config->output_pins[cnum] |= (cfg->inverted) ?
        NRFX_PWM_PIN_INVERTED : config->output_pins[cnum];

    if (instance->playing) {
        nrfx_pwm_uninit(&instance->drv_instance);
        nrfx_pwm_init(&instance->drv_instance,
                      &instance->config,
                      instance->internal_handler);

        play_current_config(instance);
    }
    return (0);
}

/**
 * Set the specified duty cycle on a PWM Channel.
 *
 * This duty cycle is a fractional duty cycle where 0 == off,
 * base_freq / pwm_freq == 100% and any value in between is on for fraction clock
 * cycles and off for (base_freq / pwm_freq)-fraction clock cycles.
 *
 * @param dev The device which the channel belongs to.
 * @param cnum The channel number. This channel should be already configured.
 * @param fraction The fraction value.
 *
 * @return 0 on success, non-zero error code on failure.
 */
static int
nrf52_pwm_set_duty_cycle(struct pwm_dev *dev, uint8_t cnum, uint16_t fraction)
{
    int inst_id = dev->pwm_instance_id;
    nrfx_pwm_config_t *config;
    bool inverted;

    if (!instances[inst_id].in_use) {
        return (EINVAL);
    }

    config = &instances[inst_id].config;
    if (config->output_pins[cnum] == NRFX_PWM_PIN_NOT_USED) {
        return (EINVAL);
    }

    inverted = ((config->output_pins[cnum] & NRFX_PWM_PIN_INVERTED) != 0);

    ((uint16_t *) &instances[inst_id].duty_cycles)[cnum] =
        (inverted) ? fraction : config->top_value - fraction;

    return (0);
}

/**
 * Enable a given PWM device.
 * This device should start playing on its previously configured channels.
 *
 * @param dev The PWM device to be enabled.
 *
 * @return 0 on success, non-zero error code on failure.
 */
int
nrf52_pwm_enable(struct pwm_dev *dev)
{
    int inst_id = dev->pwm_instance_id;
    struct nrf52_pwm_dev_global *instance = &instances[inst_id];

    nrfx_pwm_init(&instance->drv_instance,
                  &instance->config,
                  instance->internal_handler);
    play_current_config(instance);
    instance->playing = true;

    return (0);
}

/**
 * Check whether a PWM channel is enabled on a given device.
 *
 * @param dev The device which the channel belongs to.
 * @param cnum The channel being queried.
 *
 * @return true if enabled, false if not.
 */
static bool
nrf52_pwm_is_enabled(struct pwm_dev *dev)
{
    return (instances[dev->pwm_instance_id].playing);
}

/**
 * Disable the PWM device, the device will stop playing while remaining configured.
 *
 * @param dev The device to disable.
 *
 * @return 0 on success, non-zero error code on failure.
 */
static int
nrf52_pwm_disable(struct pwm_dev *dev)
{
    int inst_id = dev->pwm_instance_id;
    if (!instances[inst_id].in_use) {
        return (EINVAL);
    }

    if (!instances[inst_id].playing) {
        return (EINVAL);
    }

    nrfx_pwm_uninit(&instances[inst_id].drv_instance);
    instances[inst_id].playing = false;

    return (0);
}

/**
 * Set the frequency for the device's clock.
 * This frequency must be between 1/2 the clock frequency and
 * the clock divided by the resolution. NOTE: This will affect
 * all PWM channels belonging to the device.
 *
 * @param dev The device to configure.
 * @param freq_hz The frequency value in Hz.
 *
 * @return A value is in Hz on success, negative error code on failure.
 */
static int
nrf52_pwm_set_frequency(struct pwm_dev *dev, uint32_t freq_hz)
{
    int inst_id = dev->pwm_instance_id;
    if (!instances[inst_id].in_use) {
        return (-EINVAL);
    }

    nrf_pwm_clk_t *frq = &instances[inst_id].config.base_clock;
    uint16_t *top_value = &instances[inst_id].config.top_value;
    uint32_t base_freq_val;

    freq_hz = (freq_hz > 7999999) ? 7999999 : freq_hz;
    freq_hz = (freq_hz < 3) ? 3 : freq_hz;

    if (freq_hz > 488) {
        *frq = NRF_PWM_CLK_16MHz;
        base_freq_val = 16000000;
    } else if (freq_hz > 244) {
        *frq = NRF_PWM_CLK_8MHz;
        base_freq_val = 8000000;
    } else if (freq_hz > 122) {
        *frq = NRF_PWM_CLK_4MHz;
        base_freq_val = 4000000;
    } else if (freq_hz > 61) {
        *frq = NRF_PWM_CLK_2MHz;
        base_freq_val = 2000000;
    } else if (freq_hz > 30) {
        *frq = NRF_PWM_CLK_1MHz;
        base_freq_val = 1000000;
    } else if (freq_hz > 14) {
        *frq = NRF_PWM_CLK_500kHz;
        base_freq_val = 500000;
    } else if (freq_hz > 6) {
        *frq = NRF_PWM_CLK_250kHz;
        base_freq_val = 250000;
    } else if (freq_hz > 2) {
        *frq = NRF_PWM_CLK_125kHz;
        base_freq_val = 125000;
    }

    *top_value = base_freq_val / freq_hz;

    if (instances[inst_id].playing) {
        nrfx_pwm_uninit(&instances[inst_id].drv_instance);
        nrfx_pwm_init(&instances[inst_id].drv_instance,
                      &instances[inst_id].config,
                      instances[inst_id].internal_handler);

        play_current_config(&instances[inst_id]);
    }

    return base_freq_val;
}

/**
 * Get the underlying clock driving the PWM device.
 *
 * @param dev
 *
 * @return value is in Hz on success, error code on failure.
 */
static int
nrf52_pwm_get_clock_freq(struct pwm_dev *dev)
{
    int inst_id = dev->pwm_instance_id;
    if (!instances[inst_id].in_use) {
        return (-EINVAL);
    }

    switch (instances[inst_id].config.base_clock) {
    case NRF_PWM_CLK_16MHz:
        return (16000000);
    case NRF_PWM_CLK_8MHz:
        return (8000000);
    case NRF_PWM_CLK_4MHz:
        return (4000000);
    case NRF_PWM_CLK_2MHz:
        return (2000000);
    case NRF_PWM_CLK_1MHz:
        return (1000000);
    case NRF_PWM_CLK_500kHz:
        return (500000);
    case NRF_PWM_CLK_250kHz:
        return (250000);
    case NRF_PWM_CLK_125kHz:
        return (125000);
    }
    return (-EINVAL);
}

/**
 * Get the top value for the cycle counter, i.e. the value which sets
 * the duty cycle to 100%.
 *
 * @param dev
 *
 * @return value in cycles on success, negative error code on failure.
 */
int
nrf52_pwm_get_top_value(struct pwm_dev *dev)
{
    int inst_id = dev->pwm_instance_id;
    if (!instances[inst_id].in_use) {
        return (-EINVAL);
    }

    return (instances[inst_id].config.top_value);
}

/**
 * Get the resolution of the PWM in bits.
 *
 * @param dev The device to query.
 *
 * @return The value in bits on success, negative error code on failure.
 */
static int
nrf52_pwm_get_resolution_bits(struct pwm_dev *dev)
{
    int inst_id = dev->pwm_instance_id;
    if (!instances[inst_id].in_use) {
        return (-EINVAL);
    }

    uint16_t top_val = instances[inst_id].config.top_value;
    if (top_val >= 32768)
    {
        return (15);
    } else if (top_val >= 16384) {
        return (14);
    } else if (top_val >= 8192) {
        return (13);
    } else if (top_val >= 4096) {
        return (12);
    } else if (top_val >= 2048) {
        return (11);
    } else if (top_val >= 1024) {
        return (10);
    } else if (top_val >= 512) {
        return (9);
    } else if (top_val >= 256) {
        return (8);
    } else if (top_val >= 128) {
        return (7);
    } else if (top_val >= 64) {
        return (6);
    } else if (top_val >= 32) {
        return (5);
    } else if (top_val >= 16) {
        return (4);
    } else if (top_val >= 8) {
        return (3);
    } else if (top_val >= 4) {
        return (2);
    } else if (top_val >= 2) {
        return (1);
    }

    return (-EINVAL);
}

#if MYNEWT_VAL(OS_SYSVIEW)
#if MYNEWT_VAL(PWM_0)
static void
pwm_0_irq_handler(void)
{
    os_trace_isr_enter();
    nrfx_pwm_0_irq_handler();
    os_trace_isr_exit();
}
#endif

#if MYNEWT_VAL(PWM_1)
static void
pwm_1_irq_handler(void)
{
    os_trace_isr_enter();
    nrfx_pwm_1_irq_handler();
    os_trace_isr_exit();
}
#endif

#if MYNEWT_VAL(PWM_2)
static void
pwm_2_irq_handler(void)
{
    os_trace_isr_enter();
    nrfx_pwm_2_irq_handler();
    os_trace_isr_exit();
}
#endif

#if MYNEWT_VAL(PWM_3)
static void
pwm_3_irq_handler(void)
{
    os_trace_isr_enter();
    nrfx_pwm_3_irq_handler();
    os_trace_isr_exit();
}
#endif

#define PWM_IRQ_HANDLER(_pwm_no) \
                            (uint32_t) pwm_ ## _pwm_no ## _irq_handler
#else
#define PWM_IRQ_HANDLER(_pwm_no) \
                            (uint32_t) nrfx_pwm_ ## _pwm_no ## _irq_handler
#endif

/**
 * Callback to initialize an adc_dev structure from the os device
 * initialization callback.  This sets up a nrf52_pwm_device(), so
 * that subsequent lookups to this device allow us to manipulate it.
 */
int
nrf52_pwm_dev_init(struct os_dev *odev, void *arg)
{
    struct pwm_dev *dev;
    struct pwm_driver_funcs *pwm_funcs;
    IRQn_Type irqn;
    uint32_t irqh;

    assert(odev);
    dev = (struct pwm_dev *) odev;

    /*
     * Originally arg was expected to be a pointer to int with pwm_instance_id,
     * however this wastes sizeof(int) of memory only to keep a simple number
     * which is used only once. Instead, instance_id can be passed as int casted
     * to pointer using helper macro so let's handle both versions here:
     * - if number is valid instance_id, let's use it directly
     * - otherwise assume it's a valid pointer
     */
    if (POINTER_TO_UINT(arg) < NRF52_PWM_MAX_INSTANCES) {
        dev->pwm_instance_id = POINTER_TO_UINT(arg);
    } else {
        dev->pwm_instance_id = *((int*) arg);
        assert(dev->pwm_instance_id < NRF52_PWM_MAX_INSTANCES);
    }

    dev->pwm_chan_count = NRF_PWM_CHANNEL_COUNT;
    os_mutex_init(&dev->pwm_lock);

    OS_DEV_SETHANDLERS(odev, nrf52_pwm_open, nrf52_pwm_close);

    pwm_funcs = &dev->pwm_funcs;
    pwm_funcs->pwm_configure_device = nrf52_pwm_configure_device;
    pwm_funcs->pwm_configure_channel = nrf52_pwm_configure_channel;
    pwm_funcs->pwm_set_duty_cycle = nrf52_pwm_set_duty_cycle;
    pwm_funcs->pwm_enable = nrf52_pwm_enable;
    pwm_funcs->pwm_is_enabled = nrf52_pwm_is_enabled;
    pwm_funcs->pwm_set_frequency = nrf52_pwm_set_frequency;
    pwm_funcs->pwm_get_clock_freq = nrf52_pwm_get_clock_freq;
    pwm_funcs->pwm_get_top_value = nrf52_pwm_get_top_value;
    pwm_funcs->pwm_get_resolution_bits = nrf52_pwm_get_resolution_bits;
    pwm_funcs->pwm_disable = nrf52_pwm_disable;

    switch (dev->pwm_instance_id) {
#if MYNEWT_VAL(PWM_0)
    case 0:
        irqn = PWM0_IRQn;
        irqh = PWM_IRQ_HANDLER(0);
        break;
#endif

#if MYNEWT_VAL(PWM_1)
    case 1:
        irqn = PWM1_IRQn;
        irqh = PWM_IRQ_HANDLER(1);
        break;
#endif

#if MYNEWT_VAL(PWM_2)
    case 2:
        irqn = PWM2_IRQn;
        irqh = PWM_IRQ_HANDLER(2);
        break;
#endif

#if MYNEWT_VAL(PWM_3)
    case 3:
        irqn = PWM3_IRQn;
        irqh = PWM_IRQ_HANDLER(3);
        break;
#endif
    default:
        assert(0);
        return 0;
    }

    NVIC_SetVector(irqn, irqh);

    return (0);
}
